function BigInteger(e, t, n) {
	if (e != null) {
		if ("number" == typeof e) {
			this.fromNumber(e, t, n)
		} else {
			if (t == null && "string" != typeof e) {
				this.fromString(e, 256)
			} else {
				this.fromString(e, t)
			}
		}
	}
}
function nbi() {
	return new BigInteger(null)
}
function am1(e, t, n, r, i, s) {
	while (--s >= 0) {
		var o = t * this[e++] + n[r] + i;
		i = Math.floor(o / 67108864);
		n[r++] = o & 67108863
	}
	return i
}
function am2(e, t, n, r, i, s) {
	var o = t & 32767,
		u = t >> 15;
	while (--s >= 0) {
		var a = this[e] & 32767;
		var f = this[e++] >> 15;
		var l = u * a + f * o;
		a = o * a + ((l & 32767) << 15) + n[r] + (i & 1073741823);
		i = (a >>> 30) + (l >>> 15) + u * f + (i >>> 30);
		n[r++] = a & 1073741823
	}
	return i
}
function am3(e, t, n, r, i, s) {
	var o = t & 16383,
		u = t >> 14;
	while (--s >= 0) {
		var a = this[e] & 16383;
		var f = this[e++] >> 14;
		var l = u * a + f * o;
		a = o * a + ((l & 16383) << 14) + n[r] + i;
		i = (a >> 28) + (l >> 14) + u * f;
		n[r++] = a & 268435455
	}
	return i
}
function int2char(e) {
	return BI_RM.charAt(e)
}
function intAt(e, t) {
	var n = BI_RC[e.charCodeAt(t)];
	return n == null ? -1 : n
}
function bnpCopyTo(e) {
	for (var t = this.t - 1; t >= 0; --t) {
		e[t] = this[t]
	}
	e.t = this.t;
	e.s = this.s
}
function bnpFromInt(e) {
	this.t = 1;
	this.s = e < 0 ? -1 : 0;
	if (e > 0) {
		this[0] = e
	} else {
		if (e < -1) {
			this[0] = e + DV
		} else {
			this.t = 0
		}
	}
}
function nbv(e) {
	var t = nbi();
	t.fromInt(e);
	return t
}
function bnpFromString(e, t) {
	var n;
	if (t == 16) {
		n = 4
	} else {
		if (t == 8) {
			n = 3
		} else {
			if (t == 256) {
				n = 8
			} else {
				if (t == 2) {
					n = 1
				} else {
					if (t == 32) {
						n = 5
					} else {
						if (t == 4) {
							n = 2
						} else {
							this.fromRadix(e, t);
							return
						}
					}
				}
			}
		}
	}
	this.t = 0;
	this.s = 0;
	var r = e.length,
		i = false,
		s = 0;
	while (--r >= 0) {
		var o = n == 8 ? e[r] & 255 : intAt(e, r);
		if (o < 0) {
			if (e.charAt(r) == "-") {
				i = true
			}
			continue
		}
		i = false;
		if (s == 0) {
			this[this.t++] = o
		} else {
			if (s + n > this.DB) {
				this[this.t - 1] |= (o & (1 << this.DB - s) - 1) << s;
				this[this.t++] = o >> this.DB - s
			} else {
				this[this.t - 1] |= o << s
			}
		}
		s += n;
		if (s >= this.DB) {
			s -= this.DB
		}
	}
	if (n == 8 && (e[0] & 128) != 0) {
		this.s = -1;
		if (s > 0) {
			this[this.t - 1] |= (1 << this.DB - s) - 1 << s
		}
	}
	this.clamp();
	if (i) {
		BigInteger.ZERO.subTo(this, this)
	}
}
function bnpClamp() {
	var e = this.s & this.DM;
	while (this.t > 0 && this[this.t - 1] == e) {
		--this.t
	}
}
function bnToString(e) {
	if (this.s < 0) {
		return "-" + this.negate().toString(e)
	}
	var t;
	if (e == 16) {
		t = 4
	} else {
		if (e == 8) {
			t = 3
		} else {
			if (e == 2) {
				t = 1
			} else {
				if (e == 32) {
					t = 5
				} else {
					if (e == 4) {
						t = 2
					} else {
						return this.toRadix(e)
					}
				}
			}
		}
	}
	var n = (1 << t) - 1,
		r, i = false,
		s = "",
		o = this.t;
	var u = this.DB - o * this.DB % t;
	if (o-- > 0) {
		if (u < this.DB && (r = this[o] >> u) > 0) {
			i = true;
			s = int2char(r)
		}
		while (o >= 0) {
			if (u < t) {
				r = (this[o] & (1 << u) - 1) << t - u;
				r |= this[--o] >> (u += this.DB - t)
			} else {
				r = this[o] >> (u -= t) & n;
				if (u <= 0) {
					u += this.DB;
					--o
				}
			}
			if (r > 0) {
				i = true
			}
			if (i) {
				s += int2char(r)
			}
		}
	}
	return i ? s : "0"
}
function bnNegate() {
	var e = nbi();
	BigInteger.ZERO.subTo(this, e);
	return e
}
function bnAbs() {
	return this.s < 0 ? this.negate() : this
}
function bnCompareTo(e) {
	var t = this.s - e.s;
	if (t != 0) {
		return t
	}
	var n = this.t;
	t = n - e.t;
	if (t != 0) {
		return t
	}
	while (--n >= 0) {
		if ((t = this[n] - e[n]) != 0) {
			return t
		}
	}
	return 0
}
function nbits(e) {
	var t = 1,
		n;
	if ((n = e >>> 16) != 0) {
		e = n;
		t += 16
	}
	if ((n = e >> 8) != 0) {
		e = n;
		t += 8
	}
	if ((n = e >> 4) != 0) {
		e = n;
		t += 4
	}
	if ((n = e >> 2) != 0) {
		e = n;
		t += 2
	}
	if ((n = e >> 1) != 0) {
		e = n;
		t += 1
	}
	return t
}
function bnBitLength() {
	if (this.t <= 0) {
		return 0
	}
	return this.DB * (this.t - 1) + nbits(this[this.t - 1] ^ this.s & this.DM)
}
function bnpDLShiftTo(e, t) {
	var n;
	for (n = this.t - 1; n >= 0; --n) {
		t[n + e] = this[n]
	}
	for (n = e - 1; n >= 0; --n) {
		t[n] = 0
	}
	t.t = this.t + e;
	t.s = this.s
}
function bnpDRShiftTo(e, t) {
	for (var n = e; n < this.t; ++n) {
		t[n - e] = this[n]
	}
	t.t = Math.max(this.t - e, 0);
	t.s = this.s
}
function bnpLShiftTo(e, t) {
	var n = e % this.DB;
	var r = this.DB - n;
	var i = (1 << r) - 1;
	var s = Math.floor(e / this.DB),
		o = this.s << n & this.DM,
		u;
	for (u = this.t - 1; u >= 0; --u) {
		t[u + s + 1] = this[u] >> r | o;
		o = (this[u] & i) << n
	}
	for (u = s - 1; u >= 0; --u) {
		t[u] = 0
	}
	t[s] = o;
	t.t = this.t + s + 1;
	t.s = this.s;
	t.clamp()
}
function bnpRShiftTo(e, t) {
	t.s = this.s;
	var n = Math.floor(e / this.DB);
	if (n >= this.t) {
		t.t = 0;
		return
	}
	var r = e % this.DB;
	var i = this.DB - r;
	var s = (1 << r) - 1;
	t[0] = this[n] >> r;
	for (var o = n + 1; o < this.t; ++o) {
		t[o - n - 1] |= (this[o] & s) << i;
		t[o - n] = this[o] >> r
	}
	if (r > 0) {
		t[this.t - n - 1] |= (this.s & s) << i
	}
	t.t = this.t - n;
	t.clamp()
}
function bnpSubTo(e, t) {
	var n = 0,
		r = 0,
		i = Math.min(e.t, this.t);
	while (n < i) {
		r += this[n] - e[n];
		t[n++] = r & this.DM;
		r >>= this.DB
	}
	if (e.t < this.t) {
		r -= e.s;
		while (n < this.t) {
			r += this[n];
			t[n++] = r & this.DM;
			r >>= this.DB
		}
		r += this.s
	} else {
		r += this.s;
		while (n < e.t) {
			r -= e[n];
			t[n++] = r & this.DM;
			r >>= this.DB
		}
		r -= e.s
	}
	t.s = r < 0 ? -1 : 0;
	if (r < -1) {
		t[n++] = this.DV + r
	} else {
		if (r > 0) {
			t[n++] = r
		}
	}
	t.t = n;
	t.clamp()
}
function bnpMultiplyTo(e, t) {
	var n = this.abs(),
		r = e.abs();
	var i = n.t;
	t.t = i + r.t;
	while (--i >= 0) {
		t[i] = 0
	}
	for (i = 0; i < r.t; ++i) {
		t[i + n.t] = n.am(0, r[i], t, i, 0, n.t)
	}
	t.s = 0;
	t.clamp();
	if (this.s != e.s) {
		BigInteger.ZERO.subTo(t, t)
	}
}
function bnpSquareTo(e) {
	var t = this.abs();
	var n = e.t = 2 * t.t;
	while (--n >= 0) {
		e[n] = 0
	}
	for (n = 0; n < t.t - 1; ++n) {
		var r = t.am(n, t[n], e, 2 * n, 0, 1);
		if ((e[n + t.t] += t.am(n + 1, 2 * t[n], e, 2 * n + 1, r, t.t - n - 1)) >= t.DV) {
			e[n + t.t] -= t.DV;
			e[n + t.t + 1] = 1
		}
	}
	if (e.t > 0) {
		e[e.t - 1] += t.am(n, t[n], e, 2 * n, 0, 1)
	}
	e.s = 0;
	e.clamp()
}
function bnpDivRemTo(e, t, n) {
	var r = e.abs();
	if (r.t <= 0) {
		return
	}
	var i = this.abs();
	if (i.t < r.t) {
		if (t != null) {
			t.fromInt(0)
		}
		if (n != null) {
			this.copyTo(n)
		}
		return
	}
	if (n == null) {
		n = nbi()
	}
	var s = nbi(),
		o = this.s,
		u = e.s;
	var a = this.DB - nbits(r[r.t - 1]);
	if (a > 0) {
		r.lShiftTo(a, s);
		i.lShiftTo(a, n)
	} else {
		r.copyTo(s);
		i.copyTo(n)
	}
	var f = s.t;
	var l = s[f - 1];
	if (l == 0) {
		return
	}
	var c = l * (1 << this.F1) + (f > 1 ? s[f - 2] >> this.F2 : 0);
	var h = this.FV / c,
		p = (1 << this.F1) / c,
		d = 1 << this.F2;
	var v = n.t,
		m = v - f,
		g = t == null ? nbi() : t;
	s.dlShiftTo(m, g);
	if (n.compareTo(g) >= 0) {
		n[n.t++] = 1;
		n.subTo(g, n)
	}
	BigInteger.ONE.dlShiftTo(f, g);
	g.subTo(s, s);
	while (s.t < f) {
		s[s.t++] = 0
	}
	while (--m >= 0) {
		var y = n[--v] == l ? this.DM : Math.floor(n[v] * h + (n[v - 1] + d) * p);
		if ((n[v] += s.am(0, y, n, m, 0, f)) < y) {
			s.dlShiftTo(m, g);
			n.subTo(g, n);
			while (n[v] < --y) {
				n.subTo(g, n)
			}
		}
	}
	if (t != null) {
		n.drShiftTo(f, t);
		if (o != u) {
			BigInteger.ZERO.subTo(t, t)
		}
	}
	n.t = f;
	n.clamp();
	if (a > 0) {
		n.rShiftTo(a, n)
	}
	if (o < 0) {
		BigInteger.ZERO.subTo(n, n)
	}
}
function bnMod(e) {
	var t = nbi();
	this.abs().divRemTo(e, null, t);
	if (this.s < 0 && t.compareTo(BigInteger.ZERO) > 0) {
		e.subTo(t, t)
	}
	return t
}
function Classic(e) {
	this.m = e
}
function cConvert(e) {
	if (e.s < 0 || e.compareTo(this.m) >= 0) {
		return e.mod(this.m)
	} else {
		return e
	}
}
function cRevert(e) {
	return e
}
function cReduce(e) {
	e.divRemTo(this.m, null, e)
}
function cMulTo(e, t, n) {
	e.multiplyTo(t, n);
	this.reduce(n)
}
function cSqrTo(e, t) {
	e.squareTo(t);
	this.reduce(t)
}
function bnpInvDigit() {
	if (this.t < 1) {
		return 0
	}
	var e = this[0];
	if ((e & 1) == 0) {
		return 0
	}
	var t = e & 3;
	t = t * (2 - (e & 15) * t) & 15;
	t = t * (2 - (e & 255) * t) & 255;
	t = t * (2 - ((e & 65535) * t & 65535)) & 65535;
	t = t * (2 - e * t % this.DV) % this.DV;
	return t > 0 ? this.DV - t : -t
}
function Montgomery(e) {
	this.m = e;
	this.mp = e.invDigit();
	this.mpl = this.mp & 32767;
	this.mph = this.mp >> 15;
	this.um = (1 << e.DB - 15) - 1;
	this.mt2 = 2 * e.t
}
function montConvert(e) {
	var t = nbi();
	e.abs().dlShiftTo(this.m.t, t);
	t.divRemTo(this.m, null, t);
	if (e.s < 0 && t.compareTo(BigInteger.ZERO) > 0) {
		this.m.subTo(t, t)
	}
	return t
}
function montRevert(e) {
	var t = nbi();
	e.copyTo(t);
	this.reduce(t);
	return t
}
function montReduce(e) {
	while (e.t <= this.mt2) {
		e[e.t++] = 0
	}
	for (var t = 0; t < this.m.t; ++t) {
		var n = e[t] & 32767;
		var r = n * this.mpl + ((n * this.mph + (e[t] >> 15) * this.mpl & this.um) << 15) & e.DM;
		n = t + this.m.t;
		e[n] += this.m.am(0, r, e, t, 0, this.m.t);
		while (e[n] >= e.DV) {
			e[n] -= e.DV;
			e[++n]++
		}
	}
	e.clamp();
	e.drShiftTo(this.m.t, e);
	if (e.compareTo(this.m) >= 0) {
		e.subTo(this.m, e)
	}
}
function montSqrTo(e, t) {
	e.squareTo(t);
	this.reduce(t)
}
function montMulTo(e, t, n) {
	e.multiplyTo(t, n);
	this.reduce(n)
}
function bnpIsEven() {
	return (this.t > 0 ? this[0] & 1 : this.s) == 0
}
function bnpExp(e, t) {
	if (e > 4294967295 || e < 1) {
		return BigInteger.ONE
	}
	var n = nbi(),
		r = nbi(),
		i = t.convert(this),
		s = nbits(e) - 1;
	i.copyTo(n);
	while (--s >= 0) {
		t.sqrTo(n, r);
		if ((e & 1 << s) > 0) {
			t.mulTo(r, i, n)
		} else {
			var o = n;
			n = r;
			r = o
		}
	}
	return t.revert(n)
}
function bnModPowInt(e, t) {
	var n;
	if (e < 256 || t.isEven()) {
		n = new Classic(t)
	} else {
		n = new Montgomery(t)
	}
	return this.exp(e, n)
}
function bnClone() {
	var e = nbi();
	this.copyTo(e);
	return e
}
function bnIntValue() {
	if (this.s < 0) {
		if (this.t == 1) {
			return this[0] - this.DV
		} else {
			if (this.t == 0) {
				return -1
			}
		}
	} else {
		if (this.t == 1) {
			return this[0]
		} else {
			if (this.t == 0) {
				return 0
			}
		}
	}
	return (this[1] & (1 << 32 - this.DB) - 1) << this.DB | this[0]
}
function bnByteValue() {
	return this.t == 0 ? this.s : this[0] << 24 >> 24
}
function bnShortValue() {
	return this.t == 0 ? this.s : this[0] << 16 >> 16
}
function bnpChunkSize(e) {
	return Math.floor(Math.LN2 * this.DB / Math.log(e))
}
function bnSigNum() {
	if (this.s < 0) {
		return -1
	} else {
		if (this.t <= 0 || this.t == 1 && this[0] <= 0) {
			return 0
		} else {
			return 1
		}
	}
}
function bnpToRadix(e) {
	if (e == null) {
		e = 10
	}
	if (this.signum() == 0 || e < 2 || e > 36) {
		return "0"
	}
	var t = this.chunkSize(e);
	var n = Math.pow(e, t);
	var r = nbv(n),
		i = nbi(),
		s = nbi(),
		o = "";
	this.divRemTo(r, i, s);
	while (i.signum() > 0) {
		o = (n + s.intValue()).toString(e).substr(1) + o;
		i.divRemTo(r, i, s)
	}
	return s.intValue().toString(e) + o
}
function bnpFromRadix(e, t) {
	this.fromInt(0);
	if (t == null) {
		t = 10
	}
	var n = this.chunkSize(t);
	var r = Math.pow(t, n),
		i = false,
		s = 0,
		o = 0;
	for (var u = 0; u < e.length; ++u) {
		var a = intAt(e, u);
		if (a < 0) {
			if (e.charAt(u) == "-" && this.signum() == 0) {
				i = true
			}
			continue
		}
		o = t * o + a;
		if (++s >= n) {
			this.dMultiply(r);
			this.dAddOffset(o, 0);
			s = 0;
			o = 0
		}
	}
	if (s > 0) {
		this.dMultiply(Math.pow(t, s));
		this.dAddOffset(o, 0)
	}
	if (i) {
		BigInteger.ZERO.subTo(this, this)
	}
}
function bnpFromNumber(e, t, n) {
	if ("number" == typeof t) {
		if (e < 2) {
			this.fromInt(1)
		} else {
			this.fromNumber(e, n);
			if (!this.testBit(e - 1)) {
				this.bitwiseTo(BigInteger.ONE.shiftLeft(e - 1), op_or, this)
			}
			if (this.isEven()) {
				this.dAddOffset(1, 0)
			}
			while (!this.isProbablePrime(t)) {
				this.dAddOffset(2, 0);
				if (this.bitLength() > e) {
					this.subTo(BigInteger.ONE.shiftLeft(e - 1), this)
				}
			}
		}
	} else {
		var r = new Array,
			i = e & 7;
		r.length = (e >> 3) + 1;
		t.nextBytes(r);
		if (i > 0) {
			r[0] &= (1 << i) - 1
		} else {
			r[0] = 0
		}
		this.fromString(r, 256)
	}
}
function bnToByteArray() {
	var e = this.t,
		t = new Array;
	t[0] = this.s;
	var n = this.DB - e * this.DB % 8,
		r, i = 0;
	if (e-- > 0) {
		if (n < this.DB && (r = this[e] >> n) != (this.s & this.DM) >> n) {
			t[i++] = r | this.s << this.DB - n
		}
		while (e >= 0) {
			if (n < 8) {
				r = (this[e] & (1 << n) - 1) << 8 - n;
				r |= this[--e] >> (n += this.DB - 8)
			} else {
				r = this[e] >> (n -= 8) & 255;
				if (n <= 0) {
					n += this.DB;
					--e
				}
			}
			if ((r & 128) != 0) {
				r |= -256
			}
			if (i == 0 && (this.s & 128) != (r & 128)) {
				++i
			}
			if (i > 0 || r != this.s) {
				t[i++] = r
			}
		}
	}
	return t
}
function bnEquals(e) {
	return this.compareTo(e) == 0
}
function bnMin(e) {
	return this.compareTo(e) < 0 ? this : e
}
function bnMax(e) {
	return this.compareTo(e) > 0 ? this : e
}
function bnpBitwiseTo(e, t, n) {
	var r, i, s = Math.min(e.t, this.t);
	for (r = 0; r < s; ++r) {
		n[r] = t(this[r], e[r])
	}
	if (e.t < this.t) {
		i = e.s & this.DM;
		for (r = s; r < this.t; ++r) {
			n[r] = t(this[r], i)
		}
		n.t = this.t
	} else {
		i = this.s & this.DM;
		for (r = s; r < e.t; ++r) {
			n[r] = t(i, e[r])
		}
		n.t = e.t
	}
	n.s = t(this.s, e.s);
	n.clamp()
}
function op_and(e, t) {
	return e & t
}
function bnAnd(e) {
	var t = nbi();
	this.bitwiseTo(e, op_and, t);
	return t
}
function op_or(e, t) {
	return e | t
}
function bnOr(e) {
	var t = nbi();
	this.bitwiseTo(e, op_or, t);
	return t
}
function op_xor(e, t) {
	return e ^ t
}
function bnXor(e) {
	var t = nbi();
	this.bitwiseTo(e, op_xor, t);
	return t
}
function op_andnot(e, t) {
	return e & ~t
}
function bnAndNot(e) {
	var t = nbi();
	this.bitwiseTo(e, op_andnot, t);
	return t
}
function bnNot() {
	var e = nbi();
	for (var t = 0; t < this.t; ++t) {
		e[t] = this.DM & ~this[t]
	}
	e.t = this.t;
	e.s = ~this.s;
	return e
}
function bnShiftLeft(e) {
	var t = nbi();
	if (e < 0) {
		this.rShiftTo(-e, t)
	} else {
		this.lShiftTo(e, t)
	}
	return t
}
function bnShiftRight(e) {
	var t = nbi();
	if (e < 0) {
		this.lShiftTo(-e, t)
	} else {
		this.rShiftTo(e, t)
	}
	return t
}
function lbit(e) {
	if (e == 0) {
		return -1
	}
	var t = 0;
	if ((e & 65535) == 0) {
		e >>= 16;
		t += 16
	}
	if ((e & 255) == 0) {
		e >>= 8;
		t += 8
	}
	if ((e & 15) == 0) {
		e >>= 4;
		t += 4
	}
	if ((e & 3) == 0) {
		e >>= 2;
		t += 2
	}
	if ((e & 1) == 0) {
		++t
	}
	return t
}
function bnGetLowestSetBit() {
	for (var e = 0; e < this.t; ++e) {
		if (this[e] != 0) {
			return e * this.DB + lbit(this[e])
		}
	}
	if (this.s < 0) {
		return this.t * this.DB
	}
	return -1
}
function cbit(e) {
	var t = 0;
	while (e != 0) {
		e &= e - 1;
		++t
	}
	return t
}
function bnBitCount() {
	var e = 0,
		t = this.s & this.DM;
	for (var n = 0; n < this.t; ++n) {
		e += cbit(this[n] ^ t)
	}
	return e
}
function bnTestBit(e) {
	var t = Math.floor(e / this.DB);
	if (t >= this.t) {
		return this.s != 0
	}
	return (this[t] & 1 << e % this.DB) != 0
}
function bnpChangeBit(e, t) {
	var n = BigInteger.ONE.shiftLeft(e);
	this.bitwiseTo(n, t, n);
	return n
}
function bnSetBit(e) {
	return this.changeBit(e, op_or)
}
function bnClearBit(e) {
	return this.changeBit(e, op_andnot)
}
function bnFlipBit(e) {
	return this.changeBit(e, op_xor)
}
function bnpAddTo(e, t) {
	var n = 0,
		r = 0,
		i = Math.min(e.t, this.t);
	while (n < i) {
		r += this[n] + e[n];
		t[n++] = r & this.DM;
		r >>= this.DB
	}
	if (e.t < this.t) {
		r += e.s;
		while (n < this.t) {
			r += this[n];
			t[n++] = r & this.DM;
			r >>= this.DB
		}
		r += this.s
	} else {
		r += this.s;
		while (n < e.t) {
			r += e[n];
			t[n++] = r & this.DM;
			r >>= this.DB
		}
		r += e.s
	}
	t.s = r < 0 ? -1 : 0;
	if (r > 0) {
		t[n++] = r
	} else {
		if (r < -1) {
			t[n++] = this.DV + r
		}
	}
	t.t = n;
	t.clamp()
}
function bnAdd(e) {
	var t = nbi();
	this.addTo(e, t);
	return t
}
function bnSubtract(e) {
	var t = nbi();
	this.subTo(e, t);
	return t
}
function bnMultiply(e) {
	var t = nbi();
	this.multiplyTo(e, t);
	return t
}
function bnDivide(e) {
	var t = nbi();
	this.divRemTo(e, t, null);
	return t
}
function bnRemainder(e) {
	var t = nbi();
	this.divRemTo(e, null, t);
	return t
}
function bnDivideAndRemainder(e) {
	var t = nbi(),
		n = nbi();
	this.divRemTo(e, t, n);
	return new Array(t, n)
}
function bnpDMultiply(e) {
	this[this.t] = this.am(0, e - 1, this, 0, 0, this.t);
	++this.t;
	this.clamp()
}
function bnpDAddOffset(e, t) {
	if (e == 0) {
		return
	}
	while (this.t <= t) {
		this[this.t++] = 0
	}
	this[t] += e;
	while (this[t] >= this.DV) {
		this[t] -= this.DV;
		if (++t >= this.t) {
			this[this.t++] = 0
		}++this[t]
	}
}
function NullExp() {}
function nNop(e) {
	return e
}
function nMulTo(e, t, n) {
	e.multiplyTo(t, n)
}
function nSqrTo(e, t) {
	e.squareTo(t)
}
function bnPow(e) {
	return this.exp(e, new NullExp)
}
function bnpMultiplyLowerTo(e, t, n) {
	var r = Math.min(this.t + e.t, t);
	n.s = 0;
	n.t = r;
	while (r > 0) {
		n[--r] = 0
	}
	var i;
	for (i = n.t - this.t; r < i; ++r) {
		n[r + this.t] = this.am(0, e[r], n, r, 0, this.t)
	}
	for (i = Math.min(e.t, t); r < i; ++r) {
		this.am(0, e[r], n, r, 0, t - r)
	}
	n.clamp()
}
function bnpMultiplyUpperTo(e, t, n) {
	--t;
	var r = n.t = this.t + e.t - t;
	n.s = 0;
	while (--r >= 0) {
		n[r] = 0
	}
	for (r = Math.max(t - this.t, 0); r < e.t; ++r) {
		n[this.t + r - t] = this.am(t - r, e[r], n, 0, 0, this.t + r - t)
	}
	n.clamp();
	n.drShiftTo(1, n)
}
function Barrett(e) {
	this.r2 = nbi();
	this.q3 = nbi();
	BigInteger.ONE.dlShiftTo(2 * e.t, this.r2);
	this.mu = this.r2.divide(e);
	this.m = e
}
function barrettConvert(e) {
	if (e.s < 0 || e.t > 2 * this.m.t) {
		return e.mod(this.m)
	} else {
		if (e.compareTo(this.m) < 0) {
			return e
		} else {
			var t = nbi();
			e.copyTo(t);
			this.reduce(t);
			return t
		}
	}
}
function barrettRevert(e) {
	return e
}
function barrettReduce(e) {
	e.drShiftTo(this.m.t - 1, this.r2);
	if (e.t > this.m.t + 1) {
		e.t = this.m.t + 1;
		e.clamp()
	}
	this.mu.multiplyUpperTo(this.r2, this.m.t + 1, this.q3);
	this.m.multiplyLowerTo(this.q3, this.m.t + 1, this.r2);
	while (e.compareTo(this.r2) < 0) {
		e.dAddOffset(1, this.m.t + 1)
	}
	e.subTo(this.r2, e);
	while (e.compareTo(this.m) >= 0) {
		e.subTo(this.m, e)
	}
}
function barrettSqrTo(e, t) {
	e.squareTo(t);
	this.reduce(t)
}
function barrettMulTo(e, t, n) {
	e.multiplyTo(t, n);
	this.reduce(n)
}
function bnModPow(e, t) {
	var n = e.bitLength(),
		r, i = nbv(1),
		s;
	if (n <= 0) {
		return i
	} else {
		if (n < 18) {
			r = 1
		} else {
			if (n < 48) {
				r = 3
			} else {
				if (n < 144) {
					r = 4
				} else {
					if (n < 768) {
						r = 5
					} else {
						r = 6
					}
				}
			}
		}
	}
	if (n < 8) {
		s = new Classic(t)
	} else {
		if (t.isEven()) {
			s = new Barrett(t)
		} else {
			s = new Montgomery(t)
		}
	}
	var o = new Array,
		u = 3,
		a = r - 1,
		f = (1 << r) - 1;
	o[1] = s.convert(this);
	if (r > 1) {
		var l = nbi();
		s.sqrTo(o[1], l);
		while (u <= f) {
			o[u] = nbi();
			s.mulTo(l, o[u - 2], o[u]);
			u += 2
		}
	}
	var c = e.t - 1,
		h, p = true,
		d = nbi(),
		v;
	n = nbits(e[c]) - 1;
	while (c >= 0) {
		if (n >= a) {
			h = e[c] >> n - a & f
		} else {
			h = (e[c] & (1 << n + 1) - 1) << a - n;
			if (c > 0) {
				h |= e[c - 1] >> this.DB + n - a
			}
		}
		u = r;
		while ((h & 1) == 0) {
			h >>= 1;
			--u
		}
		if ((n -= u) < 0) {
			n += this.DB;
			--c
		}
		if (p) {
			o[h].copyTo(i);
			p = false
		} else {
			while (u > 1) {
				s.sqrTo(i, d);
				s.sqrTo(d, i);
				u -= 2
			}
			if (u > 0) {
				s.sqrTo(i, d)
			} else {
				v = i;
				i = d;
				d = v
			}
			s.mulTo(d, o[h], i)
		}
		while (c >= 0 && (e[c] & 1 << n) == 0) {
			s.sqrTo(i, d);
			v = i;
			i = d;
			d = v;
			if (--n < 0) {
				n = this.DB - 1;
				--c
			}
		}
	}
	return s.revert(i)
}
function bnGCD(e) {
	var t = this.s < 0 ? this.negate() : this.clone();
	var n = e.s < 0 ? e.negate() : e.clone();
	if (t.compareTo(n) < 0) {
		var r = t;
		t = n;
		n = r
	}
	var i = t.getLowestSetBit(),
		s = n.getLowestSetBit();
	if (s < 0) {
		return t
	}
	if (i < s) {
		s = i
	}
	if (s > 0) {
		t.rShiftTo(s, t);
		n.rShiftTo(s, n)
	}
	while (t.signum() > 0) {
		if ((i = t.getLowestSetBit()) > 0) {
			t.rShiftTo(i, t)
		}
		if ((i = n.getLowestSetBit()) > 0) {
			n.rShiftTo(i, n)
		}
		if (t.compareTo(n) >= 0) {
			t.subTo(n, t);
			t.rShiftTo(1, t)
		} else {
			n.subTo(t, n);
			n.rShiftTo(1, n)
		}
	}
	if (s > 0) {
		n.lShiftTo(s, n)
	}
	return n
}
function bnpModInt(e) {
	if (e <= 0) {
		return 0
	}
	var t = this.DV % e,
		n = this.s < 0 ? e - 1 : 0;
	if (this.t > 0) {
		if (t == 0) {
			n = this[0] % e
		} else {
			for (var r = this.t - 1; r >= 0; --r) {
				n = (t * n + this[r]) % e
			}
		}
	}
	return n
}
function bnModInverse(e) {
	var t = e.isEven();
	if (this.isEven() && t || e.signum() == 0) {
		return BigInteger.ZERO
	}
	var n = e.clone(),
		r = this.clone();
	var i = nbv(1),
		s = nbv(0),
		o = nbv(0),
		u = nbv(1);
	while (n.signum() != 0) {
		while (n.isEven()) {
			n.rShiftTo(1, n);
			if (t) {
				if (!i.isEven() || !s.isEven()) {
					i.addTo(this, i);
					s.subTo(e, s)
				}
				i.rShiftTo(1, i)
			} else {
				if (!s.isEven()) {
					s.subTo(e, s)
				}
			}
			s.rShiftTo(1, s)
		}
		while (r.isEven()) {
			r.rShiftTo(1, r);
			if (t) {
				if (!o.isEven() || !u.isEven()) {
					o.addTo(this, o);
					u.subTo(e, u)
				}
				o.rShiftTo(1, o)
			} else {
				if (!u.isEven()) {
					u.subTo(e, u)
				}
			}
			u.rShiftTo(1, u)
		}
		if (n.compareTo(r) >= 0) {
			n.subTo(r, n);
			if (t) {
				i.subTo(o, i)
			}
			s.subTo(u, s)
		} else {
			r.subTo(n, r);
			if (t) {
				o.subTo(i, o)
			}
			u.subTo(s, u)
		}
	}
	if (r.compareTo(BigInteger.ONE) != 0) {
		return BigInteger.ZERO
	}
	if (u.compareTo(e) >= 0) {
		return u.subtract(e)
	}
	if (u.signum() < 0) {
		u.addTo(e, u)
	} else {
		return u
	}
	if (u.signum() < 0) {
		return u.add(e)
	} else {
		return u
	}
}
function bnIsProbablePrime(e) {
	var t, n = this.abs();
	if (n.t == 1 && n[0] <= lowprimes[lowprimes.length - 1]) {
		for (t = 0; t < lowprimes.length; ++t) {
			if (n[0] == lowprimes[t]) {
				return true
			}
		}
		return false
	}
	if (n.isEven()) {
		return false
	}
	t = 1;
	while (t < lowprimes.length) {
		var r = lowprimes[t],
			i = t + 1;
		while (i < lowprimes.length && r < lplim) {
			r *= lowprimes[i++]
		}
		r = n.modInt(r);
		while (t < i) {
			if (r % lowprimes[t++] == 0) {
				return false
			}
		}
	}
	return n.millerRabin(e)
}
function bnpMillerRabin(e) {
	var t = this.subtract(BigInteger.ONE);
	var n = t.getLowestSetBit();
	if (n <= 0) {
		return false
	}
	var r = t.shiftRight(n);
	e = e + 1 >> 1;
	if (e > lowprimes.length) {
		e = lowprimes.length
	}
	var i = nbi();
	for (var s = 0; s < e; ++s) {
		i.fromInt(lowprimes[s]);
		var o = i.modPow(r, this);
		if (o.compareTo(BigInteger.ONE) != 0 && o.compareTo(t) != 0) {
			var u = 1;
			while (u++ < n && o.compareTo(t) != 0) {
				o = o.modPowInt(2, this);
				if (o.compareTo(BigInteger.ONE) == 0) {
					return false
				}
			}
			if (o.compareTo(t) != 0) {
				return false
			}
		}
	}
	return true
}(function() {
	function e(e) {
		var t = e.sha1 = e.sha1 || {};
		e.md = e.md || {};
		e.md.algorithms = e.md.algorithms || {};
		e.md.sha1 = e.md.algorithms["sha1"] = t;
		var n = null;
		var r = false;
		var i = function() {
				n = String.fromCharCode(128);
				n += e.util.fillString(String.fromCharCode(0), 64);
				r = true
			};
		var s = function(e, t, n) {
				var r, i, s, o, u, a, f, l;
				var c = n.length();
				while (c >= 64) {
					i = e.h0;
					s = e.h1;
					o = e.h2;
					u = e.h3;
					a = e.h4;
					for (l = 0; l < 16; ++l) {
						r = n.getInt32();
						t[l] = r;
						f = u ^ s & (o ^ u);
						r = (i << 5 | i >>> 27) + f + a + 1518500249 + r;
						a = u;
						u = o;
						o = s << 30 | s >>> 2;
						s = i;
						i = r
					}
					for (; l < 20; ++l) {
						r = t[l - 3] ^ t[l - 8] ^ t[l - 14] ^ t[l - 16];
						r = r << 1 | r >>> 31;
						t[l] = r;
						f = u ^ s & (o ^ u);
						r = (i << 5 | i >>> 27) + f + a + 1518500249 + r;
						a = u;
						u = o;
						o = s << 30 | s >>> 2;
						s = i;
						i = r
					}
					for (; l < 32; ++l) {
						r = t[l - 3] ^ t[l - 8] ^ t[l - 14] ^ t[l - 16];
						r = r << 1 | r >>> 31;
						t[l] = r;
						f = s ^ o ^ u;
						r = (i << 5 | i >>> 27) + f + a + 1859775393 + r;
						a = u;
						u = o;
						o = s << 30 | s >>> 2;
						s = i;
						i = r
					}
					for (; l < 40; ++l) {
						r = t[l - 6] ^ t[l - 16] ^ t[l - 28] ^ t[l - 32];
						r = r << 2 | r >>> 30;
						t[l] = r;
						f = s ^ o ^ u;
						r = (i << 5 | i >>> 27) + f + a + 1859775393 + r;
						a = u;
						u = o;
						o = s << 30 | s >>> 2;
						s = i;
						i = r
					}
					for (; l < 60; ++l) {
						r = t[l - 6] ^ t[l - 16] ^ t[l - 28] ^ t[l - 32];
						r = r << 2 | r >>> 30;
						t[l] = r;
						f = s & o | u & (s ^ o);
						r = (i << 5 | i >>> 27) + f + a + 2400959708 + r;
						a = u;
						u = o;
						o = s << 30 | s >>> 2;
						s = i;
						i = r
					}
					for (; l < 80; ++l) {
						r = t[l - 6] ^ t[l - 16] ^ t[l - 28] ^ t[l - 32];
						r = r << 2 | r >>> 30;
						t[l] = r;
						f = s ^ o ^ u;
						r = (i << 5 | i >>> 27) + f + a + 3395469782 + r;
						a = u;
						u = o;
						o = s << 30 | s >>> 2;
						s = i;
						i = r
					}
					e.h0 += i;
					e.h1 += s;
					e.h2 += o;
					e.h3 += u;
					e.h4 += a;
					c -= 64
				}
			};
		t.create = function() {
			if (!r) {
				i()
			}
			var t = null;
			var o = e.util.createBuffer();
			var u = new Array(80);
			var a = {
				algorithm: "sha1",
				blockLength: 64,
				digestLength: 20,
				messageLength: 0
			};
			a.start = function() {
				a.messageLength = 0;
				o = e.util.createBuffer();
				t = {
					h0: 1732584193,
					h1: 4023233417,
					h2: 2562383102,
					h3: 271733878,
					h4: 3285377520
				};
				return a
			};
			a.start();
			a.update = function(n, r) {
				if (r === "utf8") {
					n = e.util.encodeUtf8(n)
				}
				a.messageLength += n.length;
				o.putBytes(n);
				s(t, u, o);
				if (o.read > 2048 || o.length() === 0) {
					o.compact()
				}
				return a
			};
			a.digest = function() {
				var r = a.messageLength;
				var i = e.util.createBuffer();
				i.putBytes(o.bytes());
				i.putBytes(n.substr(0, 64 - (r + 8) % 64));
				i.putInt32(r >>> 29 & 255);
				i.putInt32(r << 3 & 4294967295);
				var f = {
					h0: t.h0,
					h1: t.h1,
					h2: t.h2,
					h3: t.h3,
					h4: t.h4
				};
				s(f, u, i);
				var l = e.util.createBuffer();
				l.putInt32(f.h0);
				l.putInt32(f.h1);
				l.putInt32(f.h2);
				l.putInt32(f.h3);
				l.putInt32(f.h4);
				return l
			};
			return a
		}
	}
	var t = "sha1";
	if (typeof define !== "function") {
		if (typeof module === "object" && module.exports) {
			var n = true;
			define = function(e, t) {
				t(reqMade, module)
			}
		} else {
			if (typeof forge === "undefined") {
				forge = {}
			}
			return e(forge)
		}
	}
	var r;
	var i = function(n, i) {
			i.exports = function(i) {
				var s = r.map(function(e) {
					return n(e)
				}).concat(e);
				i = i || {};
				i.defined = i.defined || {};
				if (i.defined[t]) {
					return i[t]
				}
				i.defined[t] = true;
				for (var o = 0; o < s.length; ++o) {
					s[o](i)
				}
				return i[t]
			}
		};
	var s = define;
	define = function(e, t) {
		r = typeof e === "string" ? t.slice(2) : e.slice(2);
		if (n) {
			delete define;
			return s.apply(null, Array.prototype.slice.call(arguments, 0))
		}
		define = s;
		return define.apply(null, Array.prototype.slice.call(arguments, 0))
	};
	define(["reqMade", "module", "./util"], function() {
		i.apply(null, Array.prototype.slice.call(arguments, 0))
	})
})();
var dbits;
var canary = 0xdeadbeefcafe;
var j_lm = (canary & 16777215) == 15715070;
if (typeof navigator === "undefined") {
	BigInteger.prototype.am = am3;
	dbits = 28
} else {
	if (j_lm && navigator.appName == "Microsoft Internet Explorer") {
		BigInteger.prototype.am = am2;
		dbits = 30
	} else {
		if (j_lm && navigator.appName != "Netscape") {
			BigInteger.prototype.am = am1;
			dbits = 26
		} else {
			BigInteger.prototype.am = am3;
			dbits = 28
		}
	}
}
BigInteger.prototype.DB = dbits;
BigInteger.prototype.DM = (1 << dbits) - 1;
BigInteger.prototype.DV = 1 << dbits;
var BI_FP = 52;
BigInteger.prototype.FV = Math.pow(2, BI_FP);
BigInteger.prototype.F1 = BI_FP - dbits;
BigInteger.prototype.F2 = 2 * dbits - BI_FP;
var BI_RM = "0123456789abcdefghijklmnopqrstuvwxyz";
var BI_RC = new Array;
var rr, vv;
rr = "0".charCodeAt(0);
for (vv = 0; vv <= 9; ++vv) {
	BI_RC[rr++] = vv
}
rr = "a".charCodeAt(0);
for (vv = 10; vv < 36; ++vv) {
	BI_RC[rr++] = vv
}
rr = "A".charCodeAt(0);
for (vv = 10; vv < 36; ++vv) {
	BI_RC[rr++] = vv
}
Classic.prototype.convert = cConvert;
Classic.prototype.revert = cRevert;
Classic.prototype.reduce = cReduce;
Classic.prototype.mulTo = cMulTo;
Classic.prototype.sqrTo = cSqrTo;
Montgomery.prototype.convert = montConvert;
Montgomery.prototype.revert = montRevert;
Montgomery.prototype.reduce = montReduce;
Montgomery.prototype.mulTo = montMulTo;
Montgomery.prototype.sqrTo = montSqrTo;
BigInteger.prototype.copyTo = bnpCopyTo;
BigInteger.prototype.fromInt = bnpFromInt;
BigInteger.prototype.fromString = bnpFromString;
BigInteger.prototype.clamp = bnpClamp;
BigInteger.prototype.dlShiftTo = bnpDLShiftTo;
BigInteger.prototype.drShiftTo = bnpDRShiftTo;
BigInteger.prototype.lShiftTo = bnpLShiftTo;
BigInteger.prototype.rShiftTo = bnpRShiftTo;
BigInteger.prototype.subTo = bnpSubTo;
BigInteger.prototype.multiplyTo = bnpMultiplyTo;
BigInteger.prototype.squareTo = bnpSquareTo;
BigInteger.prototype.divRemTo = bnpDivRemTo;
BigInteger.prototype.invDigit = bnpInvDigit;
BigInteger.prototype.isEven = bnpIsEven;
BigInteger.prototype.exp = bnpExp;
BigInteger.prototype.toString = bnToString;
BigInteger.prototype.negate = bnNegate;
BigInteger.prototype.abs = bnAbs;
BigInteger.prototype.compareTo = bnCompareTo;
BigInteger.prototype.bitLength = bnBitLength;
BigInteger.prototype.mod = bnMod;
BigInteger.prototype.modPowInt = bnModPowInt;
BigInteger.ZERO = nbv(0);
BigInteger.ONE = nbv(1);
NullExp.prototype.convert = nNop;
NullExp.prototype.revert = nNop;
NullExp.prototype.mulTo = nMulTo;
NullExp.prototype.sqrTo = nSqrTo;
Barrett.prototype.convert = barrettConvert;
Barrett.prototype.revert = barrettRevert;
Barrett.prototype.reduce = barrettReduce;
Barrett.prototype.mulTo = barrettMulTo;
Barrett.prototype.sqrTo = barrettSqrTo;
var lowprimes = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509];
var lplim = (1 << 26) / lowprimes[lowprimes.length - 1];
BigInteger.prototype.chunkSize = bnpChunkSize;
BigInteger.prototype.toRadix = bnpToRadix;
BigInteger.prototype.fromRadix = bnpFromRadix;
BigInteger.prototype.fromNumber = bnpFromNumber;
BigInteger.prototype.bitwiseTo = bnpBitwiseTo;
BigInteger.prototype.changeBit = bnpChangeBit;
BigInteger.prototype.addTo = bnpAddTo;
BigInteger.prototype.dMultiply = bnpDMultiply;
BigInteger.prototype.dAddOffset = bnpDAddOffset;
BigInteger.prototype.multiplyLowerTo = bnpMultiplyLowerTo;
BigInteger.prototype.multiplyUpperTo = bnpMultiplyUpperTo;
BigInteger.prototype.modInt = bnpModInt;
BigInteger.prototype.millerRabin = bnpMillerRabin;
BigInteger.prototype.clone = bnClone;
BigInteger.prototype.intValue = bnIntValue;
BigInteger.prototype.byteValue = bnByteValue;
BigInteger.prototype.shortValue = bnShortValue;
BigInteger.prototype.signum = bnSigNum;
BigInteger.prototype.toByteArray = bnToByteArray;
BigInteger.prototype.equals = bnEquals;
BigInteger.prototype.min = bnMin;
BigInteger.prototype.max = bnMax;
BigInteger.prototype.and = bnAnd;
BigInteger.prototype.or = bnOr;
BigInteger.prototype.xor = bnXor;
BigInteger.prototype.andNot = bnAndNot;
BigInteger.prototype.not = bnNot;
BigInteger.prototype.shiftLeft = bnShiftLeft;
BigInteger.prototype.shiftRight = bnShiftRight;
BigInteger.prototype.getLowestSetBit = bnGetLowestSetBit;
BigInteger.prototype.bitCount = bnBitCount;
BigInteger.prototype.testBit = bnTestBit;
BigInteger.prototype.setBit = bnSetBit;
BigInteger.prototype.clearBit = bnClearBit;
BigInteger.prototype.flipBit = bnFlipBit;
BigInteger.prototype.add = bnAdd;
BigInteger.prototype.subtract = bnSubtract;
BigInteger.prototype.multiply = bnMultiply;
BigInteger.prototype.divide = bnDivide;
BigInteger.prototype.remainder = bnRemainder;
BigInteger.prototype.divideAndRemainder = bnDivideAndRemainder;
BigInteger.prototype.modPow = bnModPow;
BigInteger.prototype.modInverse = bnModInverse;
BigInteger.prototype.pow = bnPow;
BigInteger.prototype.gcd = bnGCD;
BigInteger.prototype.isProbablePrime = bnIsProbablePrime;
if (typeof module !== "undefined" && module.exports) {
	module.exports = BigInteger
}(function() {
	var e = {};
	if (typeof window !== "undefined") {
		var t = window.forge = window.forge || {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var t = {};
			module.exports = e
		}
	}
	t.pki = t.pki || {};
	t.pki.oids = e;
	e["1.2.840.113549.1.1.1"] = "rsaEncryption";
	e.rsaEncryption = "1.2.840.113549.1.1.1";
	e["1.2.840.113549.1.1.4"] = "md5withRSAEncryption";
	e.md5withRSAEncryption = "1.2.840.113549.1.1.4";
	e["1.2.840.113549.1.1.5"] = "sha1withRSAEncryption";
	e.sha1withRSAEncryption = "1.2.840.113549.1.1.5";
	e["1.3.14.3.2.26"] = "sha1";
	e.sha1 = "1.3.14.3.2.26";
	e["1.2.840.113549.2.5"] = "md5";
	e.md5 = "1.2.840.113549.2.5";
	e["1.2.840.113549.1.7.1"] = "data";
	e.data = "1.2.840.113549.1.7.1";
	e["1.2.840.113549.1.7.2"] = "signedData";
	e.signedData = "1.2.840.113549.1.7.2";
	e["1.2.840.113549.1.7.3"] = "envelopedData";
	e.envelopedData = "1.2.840.113549.1.7.3";
	e["1.2.840.113549.1.7.4"] = "signedAndEnvelopedData";
	e.signedAndEnvelopedData = "1.2.840.113549.1.7.4";
	e["1.2.840.113549.1.7.5"] = "digestedData";
	e.digestedData = "1.2.840.113549.1.7.5";
	e["1.2.840.113549.1.7.6"] = "encryptedData";
	e.encryptedData = "1.2.840.113549.1.7.6";
	e["1.2.840.113549.1.9.20"] = "friendlyName";
	e.friendlyName = "1.2.840.113549.1.9.20";
	e["1.2.840.113549.1.9.21"] = "localKeyId";
	e.localKeyId = "1.2.840.113549.1.9.21";
	e["1.2.840.113549.1.9.22.1"] = "x509Certificate";
	e.x509Certificate = "1.2.840.113549.1.9.22.1";
	e["1.2.840.113549.1.12.10.1.1"] = "keyBag";
	e.keyBag = "1.2.840.113549.1.12.10.1.1";
	e["1.2.840.113549.1.12.10.1.2"] = "pkcs8ShroudedKeyBag";
	e.pkcs8ShroudedKeyBag = "1.2.840.113549.1.12.10.1.2";
	e["1.2.840.113549.1.12.10.1.3"] = "certBag";
	e.certBag = "1.2.840.113549.1.12.10.1.3";
	e["1.2.840.113549.1.12.10.1.4"] = "crlBag";
	e.crlBag = "1.2.840.113549.1.12.10.1.4";
	e["1.2.840.113549.1.12.10.1.5"] = "secretBag";
	e.secretBag = "1.2.840.113549.1.12.10.1.5";
	e["1.2.840.113549.1.12.10.1.6"] = "safeContentsBag";
	e.safeContentsBag = "1.2.840.113549.1.12.10.1.6";
	e["1.2.840.113549.1.5.13"] = "pkcs5PBES2";
	e.pkcs5PBES2 = "1.2.840.113549.1.5.13";
	e["1.2.840.113549.1.5.12"] = "pkcs5PBKDF2";
	e.pkcs5PBKDF2 = "1.2.840.113549.1.5.12";
	e["2.16.840.1.101.3.4.1.2"] = "aes128-CBC";
	e["aes128-CBC"] = "2.16.840.1.101.3.4.1.2";
	e["2.16.840.1.101.3.4.1.22"] = "aes192-CBC";
	e["aes192-CBC"] = "2.16.840.1.101.3.4.1.22";
	e["2.16.840.1.101.3.4.1.42"] = "aes256-CBC";
	e["aes256-CBC"] = "2.16.840.1.101.3.4.1.42";
	e["2.5.4.3"] = "commonName";
	e.commonName = "2.5.4.3";
	e["2.5.4.5"] = "serialName";
	e.serialName = "2.5.4.5";
	e["2.5.4.6"] = "countryName";
	e.countryName = "2.5.4.6";
	e["2.5.4.7"] = "localityName";
	e.localityName = "2.5.4.7";
	e["2.5.4.8"] = "stateOrProvinceName";
	e.stateOrProvinceName = "2.5.4.8";
	e["2.5.4.10"] = "organizationName";
	e.organizationName = "2.5.4.10";
	e["2.5.4.11"] = "organizationalUnitName";
	e.organizationalUnitName = "2.5.4.11";
	e["1.2.840.113549.1.9.1"] = "emailAddress";
	e.emailAddress = "1.2.840.113549.1.9.1";
	e["2.5.29.1"] = "authorityKeyIdentifier";
	e["2.5.29.2"] = "keyAttributes";
	e["2.5.29.3"] = "certificatePolicies";
	e["2.5.29.4"] = "keyUsageRestriction";
	e["2.5.29.5"] = "policyMapping";
	e["2.5.29.6"] = "subtreesConstraint";
	e["2.5.29.7"] = "subjectAltName";
	e["2.5.29.8"] = "issuerAltName";
	e["2.5.29.9"] = "subjectDirectoryAttributes";
	e["2.5.29.10"] = "basicConstraints";
	e["2.5.29.11"] = "nameConstraints";
	e["2.5.29.12"] = "policyConstraints";
	e["2.5.29.13"] = "basicConstraints";
	e["2.5.29.14"] = "subjectKeyIdentifier";
	e.subjectKeyIdentifier = "2.5.29.14";
	e["2.5.29.15"] = "keyUsage";
	e.keyUsage = "2.5.29.15";
	e["2.5.29.16"] = "privateKeyUsagePeriod";
	e["2.5.29.17"] = "subjectAltName";
	e.subjectAltName = "2.5.29.17";
	e["2.5.29.18"] = "issuerAltName";
	e.issuerAltName = "2.5.29.18";
	e["2.5.29.19"] = "basicConstraints";
	e.basicConstraints = "2.5.29.19";
	e["2.5.29.20"] = "cRLNumber";
	e["2.5.29.21"] = "cRLReason";
	e["2.5.29.22"] = "expirationDate";
	e["2.5.29.23"] = "instructionCode";
	e["2.5.29.24"] = "invalidityDate";
	e["2.5.29.25"] = "cRLDistributionPoints";
	e["2.5.29.26"] = "issuingDistributionPoint";
	e["2.5.29.27"] = "deltaCRLIndicator";
	e["2.5.29.28"] = "issuingDistributionPoint";
	e["2.5.29.29"] = "certificateIssuer";
	e["2.5.29.30"] = "nameConstraints";
	e["2.5.29.31"] = "cRLDistributionPoints";
	e["2.5.29.32"] = "certificatePolicies";
	e["2.5.29.33"] = "policyMappings";
	e["2.5.29.34"] = "policyConstraints";
	e["2.5.29.35"] = "authorityKeyIdentifier";
	e["2.5.29.36"] = "policyConstraints";
	e["2.5.29.37"] = "extKeyUsage";
	e.extKeyUsage = "2.5.29.37";
	e["2.5.29.46"] = "freshestCRL";
	e["2.5.29.54"] = "inhibitAnyPolicy"
})();
(function() {
	if (typeof window !== "undefined") {
		var e = window.forge = window.forge || {};
		e.asn1 = {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var e = {
				util: reqMade("./util")
			};
			module.exports = e.asn1 = {}
		}
	}
	var t = e.asn1;
	t.Class = {
		UNIVERSAL: 0,
		APPLICATION: 64,
		CONTEXT_SPECIFIC: 128,
		PRIVATE: 192
	};
	t.Type = {
		NONE: 0,
		BOOLEAN: 1,
		INTEGER: 2,
		BITSTRING: 3,
		OCTETSTRING: 4,
		NULL: 5,
		OID: 6,
		ODESC: 7,
		EXTERNAL: 8,
		REAL: 9,
		ENUMERATED: 10,
		EMBEDDED: 11,
		UTF8: 12,
		ROID: 13,
		SEQUENCE: 16,
		SET: 17,
		PRINTABLESTRING: 19,
		IA5STRING: 22,
		UTCTIME: 23,
		GENERALIZEDTIME: 24
	};
	t.create = function(e, t, n, r) {
		return {
			tagClass: e,
			type: t,
			constructed: n,
			composed: n || r.constructor == Array,
			value: r
		}
	};
	var n = function(e) {
			var t = e.getByte();
			var n;
			var r = t & 128;
			if (!r) {
				n = t
			} else {
				n = e.getInt((t & 127) << 3)
			}
			return n
		};
	t.fromDer = function(r) {
		if (r.constructor == String) {
			r = e.util.createBuffer(r)
		}
		if (r.length() < 2) {
			throw {
				message: "Too few bytes to parse DER.",
				bytes: r.length()
			}
		}
		var i = r.getByte();
		var s = i & 192;
		var o = i & 31;
		var u = n(r);
		if (r.length() < u) {
			throw {
				message: "Too few bytes to read ASN.1 value.",
				detail: r.length() + " < " + u
			}
		}
		var a;
		var f = (i & 32) == 32;
		var l = f;
		if (!l && s === t.Class.UNIVERSAL && o === t.Type.BITSTRING && u > 1) {
			var c = r.read;
			var h = r.getByte();
			if (h === 0) {
				i = r.getByte();
				var p = i & 192;
				if (p === t.Class.UNIVERSAL || p === t.Class.CONTEXT_SPECIFIC) {
					try {
						var d = n(r);
						l = d === u - (r.read - c);
						if (l) {
							++c;
							--u
						}
					} catch (v) {}
				}
			}
			r.read = c
		}
		if (l) {
			a = [];
			var m = r.length();
			while (u > 0) {
				a.push(t.fromDer(r));
				u -= m - r.length();
				m = r.length()
			}
		} else {
			a = r.getBytes(u)
		}
		return t.create(s, o, f, a)
	};
	t.toDer = function(n) {
		var r = e.util.createBuffer();
		var i = n.tagClass | n.type;
		var s = e.util.createBuffer();
		if (n.composed) {
			if (n.constructed) {
				i |= 32
			} else {
				s.putByte(0)
			}
			for (var o = 0; o < n.value.length; ++o) {
				s.putBuffer(t.toDer(n.value[o]))
			}
		} else {
			s.putBytes(n.value)
		}
		r.putByte(i);
		if (s.length() <= 127) {
			r.putByte(s.length() & 127)
		} else {
			var u = s.length();
			var a = "";
			do {
				a += String.fromCharCode(u & 255);
				u = u >>> 8
			} while (u > 0);
			r.putByte(a.length | 128);
			for (var o = a.length - 1; o >= 0; --o) {
				r.putByte(a.charCodeAt(o))
			}
		}
		r.putBuffer(s);
		return r
	};
	t.oidToDer = function(t) {
		var n = t.split(".");
		var r = e.util.createBuffer();
		r.putByte(40 * parseInt(n[0], 10) + parseInt(n[1], 10));
		var i, s, o, u;
		for (var a = 2; a < n.length; ++a) {
			i = true;
			s = [];
			o = parseInt(n[a], 10);
			do {
				u = o & 127;
				o = o >>> 7;
				if (!i) {
					u |= 128
				}
				s.push(u);
				i = false
			} while (o > 0);
			for (var f = s.length - 1; f >= 0; --f) {
				r.putByte(s[f])
			}
		}
		return r
	};
	t.derToOid = function(t) {
		var n;
		if (t.constructor == String) {
			t = e.util.createBuffer(t)
		}
		var r = t.getByte();
		n = Math.floor(r / 40) + "." + r % 40;
		var i = 0;
		while (t.length() > 0) {
			r = t.getByte();
			i = i << 7;
			if (r & 128) {
				i += r & 127
			} else {
				n += "." + (i + r);
				i = 0
			}
		}
		return n
	};
	t.utcTimeToDate = function(e) {
		var t = new Date;
		var n = parseInt(e.substr(0, 2), 10);
		n = n >= 50 ? 1900 + n : 2e3 + n;
		var r = parseInt(e.substr(2, 2), 10) - 1;
		var i = parseInt(e.substr(4, 2), 10);
		var s = parseInt(e.substr(6, 2), 10);
		var o = parseInt(e.substr(8, 2), 10);
		var u = 0;
		if (e.length > 11) {
			var a = e.charAt(10);
			var f = 10;
			if (a !== "+" && a !== "-") {
				u = parseInt(e.substr(10, 2), 10);
				f += 2
			}
		}
		t.setUTCFullYear(n, r, i);
		t.setUTCHours(s, o, u, 0);
		if (f) {
			a = e.charAt(f);
			if (a === "+" || a === "-") {
				var l = parseInt(e.substr(f + 1, 2), 10);
				var c = parseInt(e.substr(f + 4, 2), 10);
				var h = l * 60 + c;
				h *= 6e4;
				if (a === "+") {
					t.setTime(+t - h)
				} else {
					t.setTime(+t + h)
				}
			}
		}
		return t
	};
	t.generalizedTimeToDate = function(e) {
		var t = new Date;
		var n = parseInt(e.substr(0, 4), 10);
		var r = parseInt(e.substr(4, 2), 10) - 1;
		var i = parseInt(e.substr(6, 2), 10);
		var s = parseInt(e.substr(8, 2), 10);
		var o = parseInt(e.substr(10, 2), 10);
		var u = parseInt(e.substr(12, 2), 10);
		var a = 0;
		var f = 0;
		var l = false;
		if (e.charAt(e.length - 1) == "Z") {
			l = true
		}
		var c = e.length - 5,
			h = e.charAt(c);
		if (h === "+" || h === "-") {
			var p = parseInt(e.substr(c + 1, 2), 10);
			var d = parseInt(e.substr(c + 4, 2), 10);
			f = p * 60 + d;
			f *= 6e4;
			if (h === "+") {
				f *= -1
			}
			l = true
		}
		if (e.charAt(14) == ".") {
			a = parseFloat(e.substr(14), 10) * 1e3
		}
		if (l) {
			t.setUTCFullYear(n, r, i);
			t.setUTCHours(s, o, u, a);
			t.setTime(+t + f)
		} else {
			t.setFullYear(n, r, i);
			t.setHours(s, o, u, a)
		}
		return t
	};
	t.dateToUtcTime = function(e) {
		var t = "";
		var n = [];
		n.push(("" + e.getUTCFullYear()).substr(2));
		n.push("" + (e.getUTCMonth() + 1));
		n.push("" + e.getUTCDate());
		n.push("" + e.getUTCHours());
		n.push("" + e.getUTCMinutes());
		n.push("" + e.getUTCSeconds());
		for (var r = 0; r < n.length; ++r) {
			if (n[r].length < 2) {
				t += "0"
			}
			t += n[r]
		}
		t += "Z";
		return t
	};
	t.validate = function(e, n, r, i) {
		var s = false;
		if ((e.tagClass === n.tagClass || typeof n.tagClass === "undefined") && (e.type === n.type || typeof n.type === "undefined")) {
			if (e.constructed === n.constructed || typeof n.constructed === "undefined") {
				s = true;
				if (n.value && n.value.constructor == Array) {
					var o = 0;
					for (var u = 0; s && u < n.value.length; ++u) {
						s = n.value[u].optional || false;
						if (e.value[o]) {
							s = t.validate(e.value[o], n.value[u], r, i);
							if (s) {
								++o
							} else {
								if (n.value[u].optional) {
									s = true
								}
							}
						}
						if (!s && i) {
							i.push("[" + n.name + '] Tag class "' + n.tagClass + '", type "' + n.type + '" expected value length "' + n.value.length + '", got "' + e.value.length + '"')
						}
					}
				}
				if (s && r) {
					if (n.capture) {
						r[n.capture] = e.value
					}
					if (n.captureAsn1) {
						r[n.captureAsn1] = e
					}
				}
			} else {
				if (i) {
					i.push("[" + n.name + '] Expected constructed "' + n.constructed + '", got "' + e.constructed + '"')
				}
			}
		} else {
			if (i) {
				if (e.tagClass !== n.tagClass) {
					i.push("[" + n.name + '] Expected tag class "' + n.tagClass + '", got "' + e.tagClass + '"')
				}
				if (e.type !== n.type) {
					i.push("[" + n.name + '] Expected type "' + n.type + '", got "' + e.type + '"')
				}
			}
		}
		return s
	};
	var r = /[^\-\ÿ]/;
	t.prettyPrint = function(n, i, s) {
		var o = "";
		i = i || 0;
		s = s || 2;
		if (i > 0) {
			o += "\n"
		}
		var u = "";
		for (var a = 0; a < i * s; ++a) {
			u += " "
		}
		o += u + "Tag: ";
		switch (n.tagClass) {
		case t.Class.UNIVERSAL:
			o += "Universal:";
			break;
		case t.Class.APPLICATION:
			o += "Application:";
			break;
		case t.Class.CONTEXT_SPECIFIC:
			o += "Context-Specific:";
			break;
		case t.Class.PRIVATE:
			o += "Private:";
			break
		}
		if (n.tagClass === t.Class.UNIVERSAL) {
			switch (n.type) {
			case t.Type.NONE:
				o += "None";
				break;
			case t.Type.BOOLEAN:
				o += "Boolean";
				break;
			case t.Type.BITSTRING:
				o += "Bit string";
				break;
			case t.Type.INTEGER:
				o += "Integer";
				break;
			case t.Type.OCTETSTRING:
				o += "Octet string";
				break;
			case t.Type.NULL:
				o += "Null";
				break;
			case t.Type.OID:
				o += "Object Identifier";
				break;
			case t.Type.ODESC:
				o += "Object Descriptor";
				break;
			case t.Type.EXTERNAL:
				o += "External or Instance of";
				break;
			case t.Type.REAL:
				o += "Real";
				break;
			case t.Type.ENUMERATED:
				o += "Enumerated";
				break;
			case t.Type.EMBEDDED:
				o += "Embedded PDV";
				break;
			case t.Type.ROID:
				o += "Relative Object Identifier";
				break;
			case t.Type.SEQUENCE:
				o += "Sequence";
				break;
			case t.Type.SET:
				o += "Set";
				break;
			case t.Type.PRINTABLESTRING:
				o += "Printable String";
				break;
			case t.Type.IA5String:
				o += "IA5String (ASCII)";
				break;
			case t.Type.UTCTIME:
				o += "UTC time";
				break;
			default:
				o += n.type;
				break
			}
		} else {
			o += n.type
		}
		o += "\n";
		o += u + "Constructed: " + n.constructed + "\n";
		if (n.composed) {
			o += u + "Sub values: " + n.value.length;
			for (var a = 0; a < n.value.length; ++a) {
				o += t.prettyPrint(n.value[a], i + 1, s);
				if (a + 1 < n.value.length) {
					o += ","
				}
			}
		} else {
			o += u + "Value: ";
			if (r.test(n.value)) {
				o += "0x" + e.util.createBuffer(n.value, "utf8").toHex()
			} else {
				if (n.value.length === 0) {
					o += "[null]"
				} else {
					o += n.value
				}
			}
		}
		return o
	}
})();
(function() {
	if (typeof window !== "undefined") {
		var e = window.forge = window.forge || {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var e = {
				asn1: reqMade("./asn1"),
				pki: {
					oids: reqMade("./oids")
				},
				random: reqMade("./random"),
				util: reqMade("./util")
			};
			BigInteger = reqMade("./jsbn");
			module.exports = e.pki.rsa = {}
		}
	}
	var t = e.asn1;
	e.pki = e.pki || {};
	e.pki.rsa = e.pki.rsa || {};
	var n = e.pki;
	var r = function(e, t, n) {
			var r;
			if (n) {
				r = e.modPow(t.e, t.n)
			} else {
				if (!t.dP) {
					t.dP = t.d.mod(t.p.subtract(BigInteger.ONE))
				}
				if (!t.dQ) {
					t.dQ = t.d.mod(t.q.subtract(BigInteger.ONE))
				}
				if (!t.qInv) {
					t.qInv = t.q.modInverse(t.p)
				}
				var i = e.mod(t.p).modPow(t.dP, t.p);
				var s = e.mod(t.q).modPow(t.dQ, t.q);
				while (i.compareTo(s) < 0) {
					i = i.add(t.p)
				}
				r = i.subtract(s).multiply(t.qInv).mod(t.p).multiply(t.q).add(s)
			}
			return r
		};
	n.rsa.encrypt = function(t, n, i) {
		var s = n.n.bitLength() >>> 3;
		if (t.length > s - 11) {
			throw {
				message: "Message is too long to encrypt.",
				length: t.length,
				max: s - 11
			}
		}
		var o = e.util.createBuffer();
		o.putByte(0);
		o.putByte(i);
		var u;
		var a = s - 3 - t.length;
		var f;
		if (i === 0 || i === 1) {
			u = false;
			f = i === 0 ? 0 : 255;
			for (var l = 0; l < a; ++l) {
				o.putByte(f)
			}
		} else {
			u = true;
			for (var l = 0; l < a; ++l) {
				f = Math.floor(Math.random() * 255) + 1;
				o.putByte(f)
			}
		}
		o.putByte(0);
		o.putBytes(t);
		var c = new BigInteger(o.toHex(), 16);
		var h = r(c, n, u);
		var p = h.toString(16);
		var d = e.util.createBuffer();
		var v = s - Math.ceil(p.length / 2);
		while (v > 0) {
			d.putByte(0);
			--v
		}
		d.putBytes(e.util.hexToBytes(p));
		return d.getBytes()
	};
	n.rsa.decrypt = function(t, n, i, s) {
		var o = e.util.createBuffer();
		var u = Math.ceil(n.n.bitLength() / 8);
		if (t.length != u) {
			throw {
				message: "Encrypted message length is invalid.",
				length: t.length,
				expected: u
			}
		}
		var a = new BigInteger(e.util.createBuffer(t).toHex(), 16);
		var f = r(a, n, i);
		var l = f.toString(16);
		var c = e.util.createBuffer();
		var h = u - Math.ceil(l.length / 2);
		while (h > 0) {
			c.putByte(0);
			--h
		}
		c.putBytes(e.util.hexToBytes(l));
		var p = c.getByte();
		var d = c.getByte();
		if (p !== 0 || i && d !== 0 && d !== 1 || !i && d != 2 || i && d === 0 && typeof s === "undefined") {
			throw {
				message: "Encryption block is invalid."
			}
		}
		var v = 0;
		if (d === 0) {
			var v = u - 3 - s;
			for (var m = 0; m < v; ++m) {
				if (c.getByte() !== 0) {
					throw {
						message: "Encryption block is invalid."
					}
				}
			}
		} else {
			if (d === 1) {
				var v = 0;
				while (c.length() > 1) {
					if (c.getByte() !== 255) {
						--c.read;
						break
					}++v
				}
			} else {
				if (d === 2) {
					var v = 0;
					while (c.length() > 1) {
						if (c.getByte() === 0) {
							--c.read;
							break
						}++v
					}
				}
			}
		}
		var g = c.getByte();
		if (g !== 0 || v !== u - 3 - c.length()) {
			throw {
				message: "Encryption block is invalid."
			}
		}
		return c.getBytes()
	};
	n.rsa.createKeyPairGenerationState = function(t, n) {
		if (typeof t === "string") {
			t = parseInt(t, 10)
		}
		t = t || 1024;
		var r = {
			nextBytes: function(t) {
				var n = +(new Date);
				var r = e.random.getBytes(t.length);
				for (var i = 0; i < t.length; ++i) {
					t[i] = r.charCodeAt(i)
				}
				var s = +(new Date)
			}
		};
		var i = {
			state: 0,
			itrs: 0,
			maxItrs: 100,
			bits: t,
			rng: r,
			e: new BigInteger((n || 65537).toString(16), 16),
			p: null,
			q: null,
			qBits: t >> 1,
			pBits: t - (t >> 1),
			pqState: 0,
			num: null,
			six: new BigInteger(null),
			addNext: 2,
			keys: null
		};
		i.six.fromInt(6);
		return i
	};
	n.rsa.stepKeyPairGenerationState = function(t, n) {
		var r = +(new Date);
		var i;
		var s = 0;
		while (t.keys === null && (n <= 0 || s < n)) {
			if (t.state === 0) {
				var o = t.p === null ? t.pBits : t.qBits;
				var u = o - 1;
				if (t.pqState === 0) {
					t.itrs = 0;
					t.num = new BigInteger(o, t.rng);
					t.r = null;
					if (t.num.isEven()) {
						t.num.dAddOffset(1, 0)
					}
					if (!t.num.testBit(u)) {
						t.num.bitwiseTo(BigInteger.ONE.shiftLeft(u), function(e, t) {
							return e | t
						}, t.num)
					}++t.pqState
				} else {
					if (t.pqState === 1) {
						if (t.addNext === null) {
							var a = t.num.mod(t.six).byteValue();
							if (a === 3) {
								t.num.mod.dAddOffset(2);
								a = 5
							}
							t.addNext = a === 1 ? 2 : 4
						}
						var f = t.num.isProbablePrime(1);
						if (f) {
							++t.pqState
						} else {
							if (t.itrs < t.maxItrs) {
								t.num.dAddOffset(t.addNext, 0);
								if (t.num.bitLength() > o) {
									t.addNext = null;
									t.num.subTo(BigInteger.ONE.shiftLeft(u), t.num)
								} else {
									t.addNext = t.addNext === 4 ? 2 : 4
								}++t.itrs
							} else {
								t.pqState = 0
							}
						}
					} else {
						if (t.pqState === 2) {
							t.pqState = t.num.subtract(BigInteger.ONE).gcd(t.e).compareTo(BigInteger.ONE) === 0 ? 3 : 0
						} else {
							if (t.pqState === 3) {
								t.pqState = 0;
								if (t.num.isProbablePrime(10)) {
									if (t.p === null) {
										t.p = t.num
									} else {
										t.q = t.num
									}
									if (t.p !== null && t.q !== null) {
										++t.state
									}
								}
								t.num = null
							}
						}
					}
				}
			} else {
				if (t.state === 1) {
					if (t.p.compareTo(t.q) < 0) {
						t.num = t.p;
						t.p = t.q;
						t.q = t.num
					}++t.state
				} else {
					if (t.state === 2) {
						t.p1 = t.p.subtract(BigInteger.ONE);
						t.q1 = t.q.subtract(BigInteger.ONE);
						t.phi = t.p1.multiply(t.q1);
						++t.state
					} else {
						if (t.state === 3) {
							if (t.phi.gcd(t.e).compareTo(BigInteger.ONE) === 0) {
								++t.state
							} else {
								t.p = null;
								t.q = null;
								t.state = 0
							}
						} else {
							if (t.state === 4) {
								t.n = t.p.multiply(t.q);
								if (t.n.bitLength() === t.bits) {
									++t.state
								} else {
									t.q = null;
									t.state = 0
								}
							} else {
								if (t.state === 5) {
									var l = t.e.modInverse(t.phi);
									t.keys = {
										privateKey: e.pki.rsa.setPrivateKey(t.n, t.e, l, t.p, t.q, l.mod(t.p1), l.mod(t.q1), t.q.modInverse(t.p)),
										publicKey: e.pki.rsa.setPublicKey(t.n, t.e)
									}
								}
							}
						}
					}
				}
			}
			i = +(new Date);
			s += i - r;
			r = i
		}
		return t.keys !== null
	};
	n.rsa.generateKeyPair = function(e, t) {
		var r = n.rsa.createKeyPairGenerationState(e, t);
		n.rsa.stepKeyPairGenerationState(r, 0);
		return r.keys
	};
	n.rsa.setPublicKey = function(e, r) {
		var i = {
			n: e,
			e: r
		};
		i.encrypt = function(e) {
			return n.rsa.encrypt(e, i, 2)
		};
		i.verify = function(e, r) {
			var s = n.rsa.decrypt(r, i, true);
			var o = t.fromDer(s);
			return e === o.value[1].value
		};
		return i
	};
	n.rsa.setPrivateKey = function(r, i, s, o, u, a, f, l) {
		var c = {
			n: r,
			e: i,
			d: s,
			p: o,
			q: u,
			dP: a,
			dQ: f,
			qInv: l
		};
		c.decrypt = function(e) {
			return n.rsa.decrypt(e, c, false)
		};
		c.sign = function(r) {
			var i;
			if (r.algorithm in e.pki.oids) {
				i = e.pki.oids[r.algorithm]
			} else {
				throw {
					message: "Unknown message digest algorithm.",
					algorithm: r.algorithm
				}
			}
			var s = t.oidToDer(i).getBytes();
			var o = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
			var u = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
			u.value.push(t.create(t.Class.UNIVERSAL, t.Type.OID, false, s));
			u.value.push(t.create(t.Class.UNIVERSAL, t.Type.NULL, false, ""));
			var a = t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, r.digest().getBytes());
			o.value.push(u);
			o.value.push(a);
			var f = t.toDer(o).getBytes();
			return n.rsa.encrypt(f, c, 1)
		};
		return c
	}
})();
(function() {
	if (typeof window !== "undefined") {
		var e = window.forge = window.forge || {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var e = {
				aes: reqMade("./aes"),
				asn1: reqMade("./asn1"),
				md: reqMade("./md"),
				pkcs5: reqMade("./pbkdf2"),
				pki: {
					oids: reqMade("./oids"),
					rsa: reqMade("./rsa")
				},
				random: reqMade("./random"),
				util: reqMade("./util")
			};
			BigInteger = reqMade("./jsbn");
			module.exports = e.pki
		}
	}
	var t = e.asn1;
	var n = e.pki = e.pki || {};
	var r = n.oids;
	var i = {};
	i.CN = r.commonName;
	i.commonName = "CN";
	i.C = r.countryName;
	i.countryName = "C";
	i.L = r.localityName;
	i.localityName = "L";
	i.ST = r.stateOrProvinceName;
	i.stateOrProvinceName = "ST";
	i.O = r.organizationName;
	i.organizationName = "O";
	i.OU = r.organizationalUnitName;
	i.organizationalUnitName = "OU";
	i.E = r.emailAddress;
	i.emailAddress = "E";
	var s = {
		name: "SubjectPublicKeyInfo",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		captureAsn1: "subjectPublicKeyInfo",
		value: [{
			name: "SubjectPublicKeyInfo.AlgorithmIdentifier",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			value: [{
				name: "AlgorithmIdentifier.algorithm",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OID,
				constructed: false,
				capture: "publicKeyOid"
			}]
		}, {
			name: "SubjectPublicKeyInfo.subjectPublicKey",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.BITSTRING,
			constructed: false,
			value: [{
				name: "SubjectPublicKeyInfo.subjectPublicKey.RSAPublicKey",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				optional: true,
				captureAsn1: "rsaPublicKey"
			}]
		}]
	};
	var o = {
		name: "RSAPublicKey",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		value: [{
			name: "RSAPublicKey.modulus",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "publicKeyModulus"
		}, {
			name: "RSAPublicKey.exponent",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "publicKeyExponent"
		}]
	};
	var u = {
		name: "Certificate",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		value: [{
			name: "Certificate.TBSCertificate",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			captureAsn1: "certTbs",
			value: [{
				name: "Certificate.TBSCertificate.version",
				tagClass: t.Class.CONTEXT_SPECIFIC,
				type: 0,
				constructed: true,
				optional: true,
				value: [{
					name: "Certificate.TBSCertificate.version.integer",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.INTEGER,
					constructed: false,
					capture: "certVersion"
				}]
			}, {
				name: "Certificate.TBSCertificate.serialNumber",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.INTEGER,
				constructed: false,
				capture: "certSerialNumber"
			}, {
				name: "Certificate.TBSCertificate.signature",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				value: [{
					name: "Certificate.TBSCertificate.signature.algorithm",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.OID,
					constructed: false,
					capture: "certSignatureOid"
				}]
			}, {
				name: "Certificate.TBSCertificate.issuer",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				captureAsn1: "certIssuer"
			}, {
				name: "Certificate.TBSCertificate.validity",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				value: [{
					name: "Certificate.TBSCertificate.validity.notBefore",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.UTCTIME,
					constructed: false,
					optional: true,
					capture: "certNotBefore"
				}, {
					name: "Certificate.TBSCertificate.validity.notBefore (generalized)",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.GENERALIZEDTIME,
					constructed: false,
					optional: true,
					capture: "certNotBeforeGeneralized"
				}, {
					name: "Certificate.TBSCertificate.validity.notAfter",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.UTCTIME,
					constructed: false,
					optional: true,
					capture: "certNotAfter"
				}, {
					name: "Certificate.TBSCertificate.validity.notAfter",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.GENERALIZEDTIME,
					constructed: false,
					optional: true,
					capture: "certNotAfterGeneralized"
				}]
			}, {
				name: "Certificate.TBSCertificate.subject",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				captureAsn1: "certSubject"
			},
			s,
			{
				name: "Certificate.TBSCertificate.issuerUniqueID",
				tagClass: t.Class.CONTEXT_SPECIFIC,
				type: 1,
				constructed: true,
				optional: true,
				value: [{
					name: "Certificate.TBSCertificate.issuerUniqueID.id",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.BITSTRING,
					constructed: false,
					capture: "certIssuerUniqueId"
				}]
			}, {
				name: "Certificate.TBSCertificate.subjectUniqueID",
				tagClass: t.Class.CONTEXT_SPECIFIC,
				type: 2,
				constructed: true,
				optional: true,
				value: [{
					name: "Certificate.TBSCertificate.subjectUniqueID.id",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.BITSTRING,
					constructed: false,
					capture: "certSubjectUniqueId"
				}]
			}, {
				name: "Certificate.TBSCertificate.extensions",
				tagClass: t.Class.CONTEXT_SPECIFIC,
				type: 3,
				constructed: true,
				captureAsn1: "certExtensions",
				optional: true
			}]
		}, {
			name: "Certificate.signatureAlgorithm",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			value: [{
				name: "Certificate.signatureAlgorithm.algorithm",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OID,
				constructed: false,
				capture: "certSignatureOid"
			}]
		}, {
			name: "Certificate.signatureValue",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.BITSTRING,
			constructed: false,
			capture: "certSignature"
		}]
	};
	var a = {
		name: "PrivateKeyInfo",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		value: [{
			name: "PrivateKeyInfo.version",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyVersion"
		}, {
			name: "PrivateKeyInfo.privateKeyAlgorithm",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			value: [{
				name: "AlgorithmIdentifier.algorithm",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OID,
				constructed: false,
				capture: "privateKeyOid"
			}]
		}, {
			name: "PrivateKeyInfo",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.OCTETSTRING,
			constructed: false,
			capture: "privateKey"
		}]
	};
	var f = {
		name: "RSAPrivateKey",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		value: [{
			name: "RSAPrivateKey.version",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyVersion"
		}, {
			name: "RSAPrivateKey.modulus",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyModulus"
		}, {
			name: "RSAPrivateKey.publicExponent",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyPublicExponent"
		}, {
			name: "RSAPrivateKey.privateExponent",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyPrivateExponent"
		}, {
			name: "RSAPrivateKey.prime1",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyPrime1"
		}, {
			name: "RSAPrivateKey.prime2",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyPrime2"
		}, {
			name: "RSAPrivateKey.exponent1",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyExponent1"
		}, {
			name: "RSAPrivateKey.exponent2",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyExponent2"
		}, {
			name: "RSAPrivateKey.coefficient",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.INTEGER,
			constructed: false,
			capture: "privateKeyCoefficient"
		}]
	};
	var l = {
		name: "EncryptedPrivateKeyInfo",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		value: [{
			name: "EncryptedPrivateKeyInfo.encryptionAlgorithm",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			value: [{
				name: "AlgorithmIdentifier.algorithm",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OID,
				constructed: false,
				capture: "encryptionOid"
			}, {
				name: "AlgorithmIdentifier.parameters",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				captureAsn1: "encryptionParams"
			}]
		}, {
			name: "EncryptedPrivateKeyInfo.encryptedData",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.OCTETSTRING,
			constructed: false,
			capture: "encryptedData"
		}]
	};
	var c = {
		name: "PBES2Algorithms",
		tagClass: t.Class.UNIVERSAL,
		type: t.Type.SEQUENCE,
		constructed: true,
		value: [{
			name: "PBES2Algorithms.keyDerivationFunc",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			value: [{
				name: "PBES2Algorithms.keyDerivationFunc.oid",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OID,
				constructed: false,
				capture: "kdfOid"
			}, {
				name: "PBES2Algorithms.params",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.SEQUENCE,
				constructed: true,
				value: [{
					name: "PBES2Algorithms.params.salt",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.OCTETSTRING,
					constructed: false,
					capture: "kdfSalt"
				}, {
					name: "PBES2Algorithms.params.iterationCount",
					tagClass: t.Class.UNIVERSAL,
					type: t.Type.INTEGER,
					onstructed: true,
					capture: "kdfIterationCount"
				}]
			}]
		}, {
			name: "PBES2Algorithms.encryptionScheme",
			tagClass: t.Class.UNIVERSAL,
			type: t.Type.SEQUENCE,
			constructed: true,
			value: [{
				name: "PBES2Algorithms.encryptionScheme.oid",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OID,
				constructed: false,
				capture: "encOid"
			}, {
				name: "PBES2Algorithms.encryptionScheme.iv",
				tagClass: t.Class.UNIVERSAL,
				type: t.Type.OCTETSTRING,
				constructed: false,
				capture: "encIv"
			}]
		}]
	};
	var h = function(e, n) {
			var s = [];
			var o, u, a;
			for (var f = 0; f < e.value.length; ++f) {
				o = e.value[f];
				for (var l = 0; l < o.value.length; ++l) {
					a = {};
					u = o.value[l];
					a.type = t.derToOid(u.value[0].value);
					a.value = u.value[1].value;
					if (a.type in r) {
						a.name = r[a.type];
						if (a.name in i) {
							a.shortName = i[a.name]
						}
					}
					if (n) {
						n.update(a.type);
						n.update(a.value)
					}
					s.push(a)
				}
			}
			return s
		};
	var p = function(e, t) {
			if (t.constructor == String) {
				t = {
					shortName: t
				}
			}
			var n = null;
			var r;
			for (var i = 0; n === null && i < e.attributes.length; ++i) {
				r = e.attributes[i];
				if (t.type && t.type === r.type) {
					n = r
				} else {
					if (t.name && t.name === r.name) {
						n = r
					} else {
						if (t.shortName && t.shortName === r.shortName) {
							n = r
						}
					}
				}
			}
			return n
		};
	var d = function(n) {
			var i = [];
			var s, o, u;
			for (var a = 0; a < n.value.length; ++a) {
				u = n.value[a];
				for (var f = 0; f < u.value.length; ++f) {
					o = u.value[f];
					s = {};
					s.id = t.derToOid(o.value[0].value);
					s.critical = false;
					if (o.value[1].type === t.Type.BOOLEAN) {
						s.critical = o.value[1].value.charCodeAt(0) !== 0;
						s.value = o.value[2].value
					} else {
						s.value = o.value[1].value
					}
					if (s.id in r) {
						s.name = r[s.id];
						if (s.name === "keyUsage") {
							var l = t.fromDer(s.value);
							var c = 0;
							var h = 0;
							if (l.value.length > 1) {
								c = l.value.charCodeAt(1);
								h = l.value.length > 2 ? l.value.charCodeAt(2) : 0
							}
							s.digitalSignature = (c & 128) == 128;
							s.nonRepudiation = (c & 64) == 64;
							s.keyEncipherment = (c & 32) == 32;
							s.dataEncipherment = (c & 16) == 16;
							s.keyAgreement = (c & 8) == 8;
							s.keyCertSign = (c & 4) == 4;
							s.cRLSign = (c & 2) == 2;
							s.encipherOnly = (c & 1) == 1;
							s.decipherOnly = (h & 128) == 128
						} else {
							if (s.name === "basicConstraints") {
								var l = t.fromDer(s.value);
								if (l.value.length > 0) {
									s.cA = l.value[0].value.charCodeAt(0) !== 0
								} else {
									s.cA = false
								}
								if (l.value.length > 1) {
									var p = e.util.createBuffer(l.value[1].value);
									s.pathLenConstraint = p.getInt(p.length() << 3)
								}
							} else {
								if (s.name === "subjectAltName" || s.name === "issuerAltName") {
									s.altNames = [];
									var d, v;
									var l = t.fromDer(s.value);
									for (var m = 0; m < l.value.length; ++m) {
										d = l.value[m];
										altName = {
											type: d.type,
											value: d.value
										};
										s.altNames.push(altName);
										switch (d.type) {
										case 1:
										case 2:
										case 6:
											break;
										case 7:
											break;
										case 8:
											altName.oid = t.derToOid(d.value);
											break;
										default:
										}
									}
								}
							}
						}
					}
					i.push(s)
				}
			}
			return i
		};
	var v = new RegExp("-----BEGIN [^-]+-----([A-Za-z0-9+/=\\s]+)-----END [^-]+-----");
	n.pemToDer = function(t) {
		var n = null;
		var r = v.exec(t);
		if (r) {
			n = e.util.createBuffer(e.util.decode64(r[1]))
		} else {
			throw "Invalid PEM format"
		}
		return n
	};
	var m = function(e, r) {
			var i = null;
			var s = n.pemToDer(e);
			var o = t.fromDer(s);
			i = r(o);
			return i
		};
	var g = function(t) {
			var n = t.toString(16);
			if (n[0] >= "8") {
				n = "00" + n
			}
			return e.util.hexToBytes(n)
		};
	n.certificateFromPem = function(e, t) {
		return m(e, function(e) {
			return n.certificateFromAsn1(e, t)
		})
	};
	n.certificateToPem = function(r, i) {
		var s = t.toDer(n.certificateToAsn1(r));
		s = e.util.encode64(s.getBytes(), i || 64);
		return "-----BEGIN CERTIFICATE-----\r\n" + s + "\r\n-----END CERTIFICATE-----"
	};
	n.publicKeyFromPem = function(e) {
		return m(e, n.publicKeyFromAsn1)
	};
	n.publicKeyToPem = function(r, i) {
		var s = t.toDer(n.publicKeyToAsn1(r));
		s = e.util.encode64(s.getBytes(), i || 64);
		return "-----BEGIN PUBLIC KEY-----\r\n" + s + "\r\n-----END PUBLIC KEY-----"
	};
	n.privateKeyFromPem = function(e) {
		return m(e, n.privateKeyFromAsn1)
	};
	n.privateKeyToPem = function(r, i) {
		var s = t.toDer(n.privateKeyToAsn1(r));
		s = e.util.encode64(s.getBytes(), i || 64);
		return "-----BEGIN RSA PRIVATE KEY-----\r\n" + s + "\r\n-----END RSA PRIVATE KEY-----"
	};
	n.createCertificate = function() {
		var s = {};
		s.version = 2;
		s.serialNumber = "00";
		s.signatureOid = null;
		s.signature = null;
		s.validity = {};
		s.validity.notBefore = new Date;
		s.validity.notAfter = new Date;
		s.issuer = {};
		s.issuer.getField = function(e) {
			return p(s.issuer, e)
		};
		s.issuer.attributes = [];
		s.issuer.hash = null;
		s.subject = {};
		s.subject.getField = function(e) {
			return p(s.subject, e)
		};
		s.subject.attributes = [];
		s.subject.hash = null;
		s.extensions = [];
		s.publicKey = null;
		s.md = null;
		var o = function(e) {
				var t;
				for (var r = 0; r < e.length; ++r) {
					t = e[r];
					if (typeof t.name === "undefined") {
						if (t.type && t.type in n.oids) {
							t.name = n.oids[t.type]
						} else {
							if (t.shortName && t.shortName in i) {
								t.name = n.oids[i[t.shortName]]
							}
						}
					}
					if (typeof t.type === "undefined") {
						if (t.name && t.name in n.oids) {
							t.type = n.oids[t.name]
						} else {
							throw {
								message: "Attribute type not specified.",
								attribute: t
							}
						}
					}
					if (typeof t.shortName === "undefined") {
						if (t.name && t.name in i) {
							t.shortName = i[t.name]
						}
					}
					if (typeof t.value === "undefined") {
						throw {
							message: "Attribute value not specified.",
							attribute: t
						}
					}
				}
			};
		s.setSubject = function(e, t) {
			o(e);
			s.subject.attributes = e;
			delete s.subject.uniqueId;
			if (t) {
				s.subject.uniqueId = t
			}
			s.subject.hash = null
		};
		s.setIssuer = function(e, t) {
			o(e);
			s.issuer.attributes = e;
			delete s.issuer.uniqueId;
			if (t) {
				s.issuer.uniqueId = t
			}
			s.issuer.hash = null
		};
		s.setExtensions = function(r) {
			var i;
			for (var o = 0; o < r.length; ++o) {
				i = r[o];
				if (typeof i.name === "undefined") {
					if (i.id && i.id in n.oids) {
						i.name = n.oids[i.id]
					}
				}
				if (typeof i.id === "undefined") {
					if (i.name && i.name in n.oids) {
						i.id = n.oids[i.name]
					} else {
						throw {
							message: "Extension ID not specified.",
							extension: i
						}
					}
				}
				if (typeof i.value === "undefined") {
					if (i.name === "keyUsage") {
						var u = 0;
						var a = 0;
						var f = 0;
						if (i.digitalSignature) {
							a |= 128;
							u = 7
						}
						if (i.nonRepudiation) {
							a |= 64;
							u = 6
						}
						if (i.keyEncipherment) {
							a |= 32;
							u = 5
						}
						if (i.dataEncipherment) {
							a |= 16;
							u = 4
						}
						if (i.keyAgreement) {
							a |= 8;
							u = 3
						}
						if (i.keyCertSign) {
							a |= 4;
							u = 2
						}
						if (i.cRLSign) {
							a |= 2;
							u = 1
						}
						if (i.encipherOnly) {
							a |= 1;
							u = 0
						}
						if (i.decipherOnly) {
							f |= 128;
							u = 7
						}
						var l = String.fromCharCode(u);
						if (f !== 0) {
							l += String.fromCharCode(a) + String.fromCharCode(f)
						} else {
							if (a !== 0) {
								l += String.fromCharCode(a)
							}
						}
						i.value = t.create(t.Class.UNIVERSAL, t.Type.BITSTRING, false, l)
					} else {
						if (i.name === "basicConstraints") {
							i.value = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
							if (i.cA) {
								i.value.value.push(t.create(t.Class.UNIVERSAL, t.Type.BOOLEAN, false, String.fromCharCode(255)))
							}
							if (i.pathLenConstraint) {
								var c = i.pathLenConstraint;
								var h = e.util.createBuffer();
								h.putInt(c, c.toString(2).length);
								i.value.value.push(t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, h.getBytes()))
							}
						} else {
							if (i.name === "subjectAltName" || i.name === "issuerAltName") {
								i.value = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
								var p;
								for (var d = 0; d < i.altNames.length; ++d) {
									p = i.altNames[d];
									var l = p.value;
									if (p.type === 8) {
										l = t.oidToDer(l)
									}
									i.value.value.push(t.create(t.Class.CONTEXT_SPECIFIC, p.type, false, l))
								}
							}
						}
					}
					if (typeof i.value === "undefined") {
						throw {
							message: "Extension value not specified.",
							extension: i
						}
					}
				}
			}
			s.extensions = r
		};
		s.getExtension = function(e) {
			if (e.constructor == String) {
				e = {
					name: e
				}
			}
			var t = null;
			var n;
			for (var r = 0; t === null && r < s.extensions.length; ++r) {
				n = s.extensions[r];
				if (e.id && n.id === e.id) {
					t = n
				} else {
					if (e.name && n.name === e.name) {
						t = n
					}
				}
			}
			return t
		};
		s.sign = function(i) {
			s.signatureOid = r.sha1withRSAEncryption;
			s.md = e.md.sha1.create();
			var o = t.toDer(n.getTBSCertificate(s));
			s.md.update(o.getBytes());
			s.signature = i.sign(s.md)
		};
		s.verify = function(e) {
			var t = false;
			if (e.md !== null) {
				t = s.publicKey.verify(e.md.digest().getBytes(), e.signature)
			}
			return t
		};
		s.isIssuer = function(e) {
			var t = false;
			var n = s.issuer;
			var r = e.subject;
			if (n.hash && r.hash) {
				t = n.hash === r.hash
			} else {
				if (n.attributes.length === r.attributes.length) {
					t = true;
					var i, o;
					for (var u = 0; t && u < n.attributes.length; ++u) {
						i = n.attributes[u];
						o = r.attributes[u];
						if (i.type !== o.type || i.value !== o.value) {
							t = false
						}
					}
				}
			}
			return t
		};
		return s
	};
	n.certificateFromAsn1 = function(i, s) {
		var o = {};
		var a = [];
		if (!t.validate(i, u, o, a)) {
			throw {
				message: "Cannot read X.509 certificate. ASN.1 object is not an X509v3 Certificate.",
				errors: a
			}
		}
		var f = t.derToOid(o.publicKeyOid);
		if (f !== n.oids.rsaEncryption) {
			throw {
				message: "Cannot read public key. OID is not RSA."
			}
		}
		var l = n.createCertificate();
		l.version = o.certVersion ? o.certVersion.charCodeAt(0) : 0;
		var c = e.util.createBuffer(o.certSerialNumber);
		l.serialNumber = c.toHex();
		l.signatureOid = e.asn1.derToOid(o.certSignatureOid);
		var p = e.util.createBuffer(o.certSignature);
		++p.read;
		l.signature = p.getBytes();
		if (o.certNotBefore !== undefined) {
			l.validity.notBefore = t.utcTimeToDate(o.certNotBefore)
		} else {
			if (o.certNotBeforeGeneralized !== undefined) {
				l.validity.notBefore = t.generalizedTimeToDate(o.certNotBeforeGeneralized)
			} else {
				throw {
					message: "Cannot read notBefore time, neither provided as UTCTime nor as GeneralizedTime."
				}
			}
		}
		if (o.certNotAfter !== undefined) {
			l.validity.notAfter = t.utcTimeToDate(o.certNotAfter)
		} else {
			if (o.certNotAfterGeneralized !== undefined) {
				l.validity.notAfter = t.generalizedTimeToDate(o.certNotAfterGeneralized)
			} else {
				throw {
					message: "Cannot read notAfter time, neither provided as UTCTime nor as GeneralizedTime."
				}
			}
		}
		if (s) {
			l.md = null;
			if (l.signatureOid in r) {
				var f = r[l.signatureOid];
				if (f === "sha1withRSAEncryption") {
					l.md = e.md.sha1.create()
				} else {
					if (f === "md5withRSAEncryption") {
						l.md = e.md.md5.create()
					}
				}
			}
			if (l.md === null) {
				throw {
					message: "Could not compute certificate digest. Unknown signature OID.",
					signatureOid: l.signatureOid
				}
			}
			var v = t.toDer(o.certTbs);
			l.md.update(v.getBytes())
		}
		var m = e.md.sha1.create();
		l.issuer.attributes = h(o.certIssuer, m);
		if (o.certIssuerUniqueId) {
			l.issuer.uniqueId = o.certIssuerUniqueId
		}
		l.issuer.hash = m.digest().toHex();
		var g = e.md.sha1.create();
		l.subject.attributes = h(o.certSubject, g);
		if (o.certSubjectUniqueId) {
			l.subject.uniqueId = o.certSubjectUniqueId
		}
		l.subject.hash = g.digest().toHex();
		if (o.certExtensions) {
			l.extensions = d(o.certExtensions)
		} else {
			l.extensions = []
		}
		l.publicKey = n.publicKeyFromAsn1(o.subjectPublicKeyInfo);
		return l
	};
	_dnToAsn1 = function(e) {
		var n = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
		var r, i;
		var s = e.attributes;
		for (var o = 0; o < s.length; ++o) {
			r = s[o];
			i = t.create(t.Class.UNIVERSAL, t.Type.SET, true, [t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.type).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.PRINTABLESTRING, false, r.value)])]);
			n.value.push(i)
		}
		return n
	};
	_extensionsToAsn1 = function(e) {
		var n = t.create(t.Class.CONTEXT_SPECIFIC, 3, true, []);
		var r = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
		n.value.push(r);
		var i, s;
		for (var o = 0; o < e.length; ++o) {
			i = e[o];
			s = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
			r.value.push(s);
			s.value.push(t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(i.id).getBytes()));
			if (i.critical) {
				s.value.push(t.create(t.Class.UNIVERSAL, t.Type.BOOLEAN, false, String.fromCharCode(255)))
			}
			var u = i.value;
			if (i.value.constructor != String) {
				u = t.toDer(u).getBytes()
			}
			s.value.push(t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, u))
		}
		return n
	};
	n.getTBSCertificate = function(r) {
		var i = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.CONTEXT_SPECIFIC, 0, true, [t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, String.fromCharCode(r.version))]), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, e.util.hexToBytes(r.serialNumber)), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.signatureOid).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.NULL, false, "")]), _dnToAsn1(r.issuer), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.UTCTIME, false, t.dateToUtcTime(r.validity.notBefore)), t.create(t.Class.UNIVERSAL, t.Type.UTCTIME, false, t.dateToUtcTime(r.validity.notAfter))]), _dnToAsn1(r.subject), n.publicKeyToAsn1(r.publicKey)]);
		if (r.issuer.uniqueId) {
			i.value.push(t.create(t.Class.CONTEXT_SPECIFIC, 1, true, [t.create(t.Class.UNIVERSAL, t.Type.BITSTRING, false, String.fromCharCode(0) + r.issuer.uniqueId)]))
		}
		if (r.subject.uniqueId) {
			i.value.push(t.create(t.Class.CONTEXT_SPECIFIC, 2, true, [t.create(t.Class.UNIVERSAL, t.Type.BITSTRING, false, String.fromCharCode(0) + r.subject.uniqueId)]))
		}
		if (r.extensions.length > 0) {
			i.value.push(_extensionsToAsn1(r.extensions))
		}
		return i
	};
	n.distinguishedNameToAsn1 = function(e) {
		return _dnToAsn1(e)
	};
	n.certificateToAsn1 = function(e) {
		return t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [n.getTBSCertificate(e), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(e.signatureOid).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.NULL, false, "")]), t.create(t.Class.UNIVERSAL, t.Type.BITSTRING, false, String.fromCharCode(0) + e.signature)])
	};
	n.createCaStore = function(t) {
		var n = {
			certs: {}
		};
		n.getIssuer = function(e) {
			var t = null;
			if (e.issuer.hash in n.certs) {
				t = n.certs[e.issuer.hash];
				if (t.constructor == Array) {
					throw {
						message: "Resolving multiple issuer matches not implemented yet."
					}
				}
			}
			return t
		};
		n.addCertificate = function(t) {
			if (t.constructor == String) {
				t = e.pki.certificateFromPem(t)
			}
			if (t.subject.hash in n.certs) {
				var r = n.certs[t.subject.hash];
				if (r.constructor != Array) {
					r = [r]
				}
				r.push(t)
			} else {
				n.certs[t.subject.hash] = t
			}
		};
		if (t) {
			for (var r = 0; r < t.length; ++r) {
				var i = t[r];
				n.addCertificate(i)
			}
		}
		return n
	};
	n.certificateError = {
		bad_certificate: "forge.pki.BadCertificate",
		unsupported_certificate: "forge.pki.UnsupportedCertificate",
		certificate_revoked: "forge.pki.CertificateRevoked",
		certificate_expired: "forge.pki.CertificateExpired",
		certificate_unknown: "forge.pki.CertificateUnknown",
		unknown_ca: "forge.pki.UnknownCertificateAuthority"
	};
	n.verifyCertificateChain = function(e, t, r) {
		t = t.slice(0);
		var i = t.slice(0);
		var s = new Date;
		var o = true;
		var u = null;
		var a = 0;
		var f, l;
		do {
			f = t.shift();
			if (s < f.validity.notBefore || s > f.validity.notAfter) {
				u = {
					message: "Certificate is not valid yet or has expired.",
					error: n.certificateError.certificate_expired,
					notBefore: f.validity.notBefore,
					notAfter: f.validity.notAfter,
					now: s
				}
			} else {
				var c = false;
				if (t.length > 0) {
					l = t[0];
					try {
						c = l.verify(f)
					} catch (h) {}
				} else {
					var p = e.getIssuer(f);
					if (p === null) {
						u = {
							message: "Certificate is not trusted.",
							error: n.certificateError.unknown_ca
						}
					} else {
						if (p.constructor != Array) {
							p = [p]
						}
						while (!c && p.length > 0) {
							l = p.shift();
							try {
								c = l.verify(f)
							} catch (h) {}
						}
					}
				}
				if (u === null && !c) {
					u = {
						message: "Certificate signature is invalid.",
						error: n.certificateError.bad_certificate
					}
				}
			}
			if (u === null && !f.isIssuer(l)) {
				u = {
					message: "Certificate issuer is invalid.",
					error: n.certificateError.bad_certificate
				}
			}
			if (u === null) {
				var d = {
					keyUsage: true,
					basicConstraints: true
				};
				for (var v = 0; u === null && v < f.extensions.length; ++v) {
					var m = f.extensions[v];
					if (m.critical && !(m.name in d)) {
						u = {
							message: "Certificate has an unsupported critical extension.",
							error: n.certificateError.unsupported_certificate
						}
					}
				}
			}
			if (!o || t.length === 0) {
				var g = f.getExtension("basicConstraints");
				var y = f.getExtension("keyUsage");
				if (y !== null) {
					if (!y.keyCertSign || g === null) {
						u = {
							message: "Certificate keyUsage or basicConstraints conflict or indicate that the certificate is not a CA. If the certificate is the only one in the chain or isn't the first then the certificate must be a valid CA.",
							error: n.certificateError.bad_certificate
						}
					}
				}
				if (u === null && g !== null && !g.cA) {
					u = {
						message: "Certificate basicConstraints indicates the certificate is not a CA.",
						error: n.certificateError.bad_certificate
					}
				}
			}
			var b = u === null ? true : u.error;
			var w = r ? r(b, a, i) : b;
			if (w === true) {
				u = null
			} else {
				if (b === true) {
					u = {
						message: "The application rejected the certificate.",
						error: n.certificateError.bad_certificate
					}
				}
				if (w || w === 0) {
					if (w.constructor === Object) {
						if (w.message) {
							u.message = w.message
						}
						if (w.error) {
							u.error = w.error
						}
					} else {
						if (w.constructor === String) {
							u.error = w
						}
					}
				}
				throw u
			}
			o = false;++a
		} while (t.length > 0);
		return true
	};
	n.publicKeyFromAsn1 = function(r) {
		var i = {};
		var u = [];
		if (!t.validate(r, s, i, u)) {
			throw {
				message: "Cannot read public key. ASN.1 object is not a SubjectPublicKeyInfo.",
				errors: u
			}
		}
		var a = t.derToOid(i.publicKeyOid);
		if (a !== n.oids.rsaEncryption) {
			throw {
				message: "Cannot read public key. Unknown OID.",
				oid: a
			}
		}
		u = [];
		if (!t.validate(i.rsaPublicKey, o, i, u)) {
			throw {
				message: "Cannot read public key. ASN.1 object is not an RSAPublicKey.",
				errors: u
			}
		}
		var f = e.util.createBuffer(i.publicKeyModulus).toHex();
		var l = e.util.createBuffer(i.publicKeyExponent).toHex();
		return n.setRsaPublicKey(new BigInteger(f, 16), new BigInteger(l, 16))
	};
	n.publicKeyToAsn1 = function(e) {
		return t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(n.oids.rsaEncryption).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.NULL, false, "")]), t.create(t.Class.UNIVERSAL, t.Type.BITSTRING, false, [t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.n)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.e))])])])
	};
	n.privateKeyFromAsn1 = function(r) {
		var i = {};
		var s = [];
		if (t.validate(r, a, i, s)) {
			r = t.fromDer(e.util.createBuffer(i.privateKey))
		}
		i = {};
		s = [];
		if (!t.validate(r, f, i, s)) {
			throw {
				message: "Cannot read private key. ASN.1 object is not an RSAPrivateKey.",
				errors: s
			}
		}
		var o, u, l, c, h, p, d, v;
		o = e.util.createBuffer(i.privateKeyModulus).toHex();
		u = e.util.createBuffer(i.privateKeyPublicExponent).toHex();
		l = e.util.createBuffer(i.privateKeyPrivateExponent).toHex();
		c = e.util.createBuffer(i.privateKeyPrime1).toHex();
		h = e.util.createBuffer(i.privateKeyPrime2).toHex();
		p = e.util.createBuffer(i.privateKeyExponent1).toHex();
		d = e.util.createBuffer(i.privateKeyExponent2).toHex();
		v = e.util.createBuffer(i.privateKeyCoefficient).toHex();
		return n.setRsaPrivateKey(new BigInteger(o, 16), new BigInteger(u, 16), new BigInteger(l, 16), new BigInteger(c, 16), new BigInteger(h, 16), new BigInteger(p, 16), new BigInteger(d, 16), new BigInteger(v, 16))
	};
	n.privateKeyToAsn1 = function(e) {
		return t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, String.fromCharCode(0)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.n)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.e)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.d)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.p)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.q)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.dP)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.dQ)), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, g(e.qInv))])
	};
	n.wrapRsaPrivateKey = function(e) {
		var n = r.rsaEncryption;
		var i = t.oidToDer(n).getBytes();
		var s = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, []);
		s.value.push(t.create(t.Class.UNIVERSAL, t.Type.OID, false, i));
		s.value.push(t.create(t.Class.UNIVERSAL, t.Type.NULL, false, ""));
		return t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, String.fromCharCode(0)), s, t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, t.toDer(e).getBytes())])
	};
	n.encryptPrivateKeyInfo = function(n, i, s) {
		s = s || {};
		s.saltSize = s.saltSize || 8;
		s.count = s.count || 2048;
		s.encAlg = s.encAlg || "aes128";
		var o = e.random.getBytes(s.saltSize);
		var u = s.count;
		var a;
		var f;
		if (s.encAlg === "aes128") {
			a = 16;
			f = r["aes128-CBC"]
		} else {
			if (s.encAlg === "aes192") {
				a = 24;
				f = r["aes192-CBC"]
			} else {
				if (s.encAlg === "aes256") {
					a = 32;
					f = r["aes256-CBC"]
				}
			}
		}
		var l = e.util.createBuffer();
		l.putInt16(u);
		var c = e.pkcs5.pbkdf2(i, o, u, a);
		var h = e.random.getBytes(16);
		var p = e.aes.createEncryptionCipher(c);
		p.start(h);
		p.update(t.toDer(n));
		p.finish();
		var d = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.pkcs5PBES2).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.pkcs5PBKDF2).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, o), t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, l.getBytes())])]), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(f).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, h)])])]), t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, p.output.getBytes())]);
		return d
	};
	n.decryptPrivateKeyInfo = function(r, i) {
		var s = null;
		var o = {};
		var u = [];
		if (!t.validate(r, l, o, u)) {
			throw {
				message: "Cannot read encrypted private key. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",
				errors: u
			}
		}
		var a = t.derToOid(o.encryptionOid);
		if (a !== n.oids.pkcs5PBES2) {
			throw {
				message: "Cannot read encrypted private key. Unsupported OID.",
				oid: a,
				supportedOids: ["pkcs5PBES2"]
			}
		}
		var f = e.util.createBuffer(o.encryptedData);
		u = [];
		if (!t.validate(o.encryptionParams, c, o, u)) {
			throw {
				message: "Cannot read password-based-encryption algorithm parameters. ASN.1 object is not a supported EncryptedPrivateKeyInfo.",
				errors: u
			}
		}
		a = t.derToOid(o.kdfOid);
		if (a !== n.oids.pkcs5PBKDF2) {
			throw {
				message: "Cannot read encrypted private key. Unsupported key derivation function OID.",
				oid: a,
				supportedOids: ["pkcs5PBKDF2"]
			}
		}
		a = t.derToOid(o.encOid);
		if (a !== n.oids["aes128-CBC"] && a !== n.oids["aes192-CBC"] && a !== n.oids["aes256-CBC"]) {
			throw {
				message: "Cannot read encrypted private key. Unsupported encryption scheme OID.",
				oid: a,
				supportedOids: ["aes128-CBC", "aes192-CBC", "aes256-CBC"]
			}
		}
		var h = o.kdfSalt;
		var p = e.util.createBuffer(o.kdfIterationCount);
		p = p.getInt(p.length() << 3);
		var d;
		if (a === n.oids["aes128-CBC"]) {
			d = 16
		} else {
			if (a === n.oids["aes192-CBC"]) {
				d = 24
			} else {
				if (a === n.oids["aes256-CBC"]) {
					d = 32
				}
			}
		}
		var v = e.pkcs5.pbkdf2(i, h, p, d);
		var m = o.encIv;
		var g = e.aes.createDecryptionCipher(v);
		g.start(m);
		g.update(f);
		if (g.finish()) {
			s = t.fromDer(g.output)
		}
		return s
	};
	n.encryptedPrivateKeyToPem = function(n, r) {
		var i = t.toDer(n);
		i = e.util.encode64(i.getBytes(), r || 64);
		return "-----BEGIN ENCRYPTED PRIVATE KEY-----\r\n" + i + "\r\n-----END ENCRYPTED PRIVATE KEY-----"
	};
	n.encryptedPrivateKeyFromPem = function(e) {
		var r = n.pemToDer(e);
		return t.fromDer(r)
	};
	n.encryptRsaPrivateKey = function(e, t, r) {
		var i = n.wrapRsaPrivateKey(n.privateKeyToAsn1(e));
		i = n.encryptPrivateKeyInfo(i, t, r);
		return n.encryptedPrivateKeyToPem(i)
	};
	n.decryptRsaPrivateKey = function(e, t) {
		var r = n.encryptedPrivateKeyFromPem(e);
		r = n.decryptPrivateKeyInfo(r, t);
		if (r !== null) {
			r = n.privateKeyFromAsn1(r)
		}
		return r
	};
	n.toPkcs12Asn1 = function(e, i, s) {
		var o = null;
		if (e !== null) {
			var u = n.wrapRsaPrivateKey(n.privateKeyToAsn1(e));
			if (s === null) {
				o = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.keyBag).getBytes()), t.create(t.Class.CONTEXT_SPECIFIC, 0, false, t.toDer(u).getBytes())])
			} else {
				o = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.pkcs8ShroudedKeyBag).getBytes()), t.create(t.Class.CONTEXT_SPECIFIC, 0, false, t.toDer(n.encryptPrivateKeyInfo(u, s)).getBytes())])
			}
		}
		if (i !== null) {
			var a = n.certificateToAsn1(i);
			var f = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.certBag).getBytes()), t.create(t.Class.CONTEXT_SPECIFIC, 0, false, t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.x509Certificate).getBytes()), t.create(t.Class.UNIVERSAL, t.Type.OCTETSTRING, false, t.toDer(a).getBytes())]))])
		}
		var l = [];
		if (e !== null) {
			l.push(o)
		}
		if (i !== null) {
			l.push(f)
		}
		var c = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, l);
		var h = t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.data).getBytes()), t.toDer(c).getBytes()])]);
		return t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.INTEGER, false, String.fromCharCode(3)), t.create(t.Class.UNIVERSAL, t.Type.SEQUENCE, true, [t.create(t.Class.UNIVERSAL, t.Type.OID, false, t.oidToDer(r.data).getBytes()), n.toDer(h).getBytes()])])
	};
	n.setRsaPublicKey = n.rsa.setPublicKey;
	n.setRsaPrivateKey = n.rsa.setPrivateKey
})();
(function() {
	if (typeof window !== "undefined") {
		var e = window.forge = window.forge || {};
		e.util = {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var e = {};
			module.exports = e.util = {}
		}
	}
	var t = e.util;
	t.ByteBuffer = function(e) {
		this.data = e || "";
		this.read = 0
	};
	t.ByteBuffer.prototype.length = function() {
		return this.data.length - this.read
	};
	t.ByteBuffer.prototype.isEmpty = function() {
		return this.data.length - this.read === 0
	};
	t.ByteBuffer.prototype.putByte = function(e) {
		this.data += String.fromCharCode(e)
	};
	t.ByteBuffer.prototype.fillWithByte = function(e, t) {
		e = String.fromCharCode(e);
		var n = this.data;
		while (t > 0) {
			if (t & 1) {
				n += e
			}
			t >>>= 1;
			if (t > 0) {
				e += e
			}
		}
		this.data = n
	};
	t.ByteBuffer.prototype.putBytes = function(e) {
		this.data += e
	};
	t.ByteBuffer.prototype.putString = function(e) {
		this.data += t.encodeUtf8(e)
	};
	t.ByteBuffer.prototype.putInt16 = function(e) {
		this.data += String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e & 255)
	};
	t.ByteBuffer.prototype.putInt24 = function(e) {
		this.data += String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e & 255)
	};
	t.ByteBuffer.prototype.putInt32 = function(e) {
		this.data += String.fromCharCode(e >> 24 & 255) + String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e & 255)
	};
	t.ByteBuffer.prototype.putInt16Le = function(e) {
		this.data += String.fromCharCode(e & 255) + String.fromCharCode(e >> 8 & 255)
	};
	t.ByteBuffer.prototype.putInt24Le = function(e) {
		this.data += String.fromCharCode(e & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e >> 16 & 255)
	};
	t.ByteBuffer.prototype.putInt32Le = function(e) {
		this.data += String.fromCharCode(e & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 24 & 255)
	};
	t.ByteBuffer.prototype.putInt = function(e, t) {
		do {
			t -= 8;
			this.data += String.fromCharCode(e >> t & 255)
		} while (t > 0)
	};
	t.ByteBuffer.prototype.putBuffer = function(e) {
		this.data += e.getBytes()
	};
	t.ByteBuffer.prototype.getByte = function() {
		return this.data.charCodeAt(this.read++)
	};
	t.ByteBuffer.prototype.getInt16 = function() {
		var e = this.data.charCodeAt(this.read) << 8 ^ this.data.charCodeAt(this.read + 1);
		this.read += 2;
		return e
	};
	t.ByteBuffer.prototype.getInt24 = function() {
		var e = this.data.charCodeAt(this.read) << 16 ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2);
		this.read += 3;
		return e
	};
	t.ByteBuffer.prototype.getInt32 = function() {
		var e = this.data.charCodeAt(this.read) << 24 ^ this.data.charCodeAt(this.read + 1) << 16 ^ this.data.charCodeAt(this.read + 2) << 8 ^ this.data.charCodeAt(this.read + 3);
		this.read += 4;
		return e
	};
	t.ByteBuffer.prototype.getInt16Le = function() {
		var e = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8;
		this.read += 2;
		return e
	};
	t.ByteBuffer.prototype.getInt24Le = function() {
		var e = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16;
		this.read += 3;
		return e
	};
	t.ByteBuffer.prototype.getInt32Le = function() {
		var e = this.data.charCodeAt(this.read) ^ this.data.charCodeAt(this.read + 1) << 8 ^ this.data.charCodeAt(this.read + 2) << 16 ^ this.data.charCodeAt(this.read + 3) << 24;
		this.read += 4;
		return e
	};
	t.ByteBuffer.prototype.getInt = function(e) {
		var t = 0;
		do {
			t = (t << e) + this.data.charCodeAt(this.read++);
			e -= 8
		} while (e > 0);
		return t
	};
	t.ByteBuffer.prototype.getBytes = function(e) {
		var t;
		if (e) {
			e = Math.min(this.length(), e);
			t = this.data.slice(this.read, this.read + e);
			this.read += e
		} else {
			if (e === 0) {
				t = ""
			} else {
				t = this.read === 0 ? this.data : this.data.slice(this.read);
				this.clear()
			}
		}
		return t
	};
	t.ByteBuffer.prototype.bytes = function(e) {
		return typeof e === "undefined" ? this.data.slice(this.read) : this.data.slice(this.read, this.read + e)
	};
	t.ByteBuffer.prototype.at = function(e) {
		return this.data.charCodeAt(this.read + e)
	};
	t.ByteBuffer.prototype.last = function() {
		return this.data.charCodeAt(this.data.length - 1)
	};
	t.ByteBuffer.prototype.copy = function() {
		var e = t.createBuffer(this.data);
		e.read = this.read;
		return e
	};
	t.ByteBuffer.prototype.compact = function() {
		if (this.read > 0) {
			this.data = this.data.slice(this.read);
			this.read = 0
		}
	};
	t.ByteBuffer.prototype.clear = function() {
		this.data = "";
		this.read = 0
	};
	t.ByteBuffer.prototype.truncate = function(e) {
		var t = Math.max(0, this.length() - e);
		this.data = this.data.substr(this.read, t);
		this.read = 0
	};
	t.ByteBuffer.prototype.toHex = function() {
		var e = "";
		for (var t = this.read; t < this.data.length; ++t) {
			var n = this.data.charCodeAt(t);
			if (n < 16) {
				e += "0"
			}
			e += n.toString(16)
		}
		return e
	};
	t.ByteBuffer.prototype.toString = function() {
		return t.decodeUtf8(this.bytes())
	};
	t.createBuffer = function(e, n) {
		n = n || "raw";
		if (e !== undefined && n === "utf8") {
			e = t.encodeUtf8(e)
		}
		return new t.ByteBuffer(e)
	};
	t.fillString = function(e, t) {
		var n = "";
		while (t > 0) {
			if (t & 1) {
				n += e
			}
			t >>>= 1;
			if (t > 0) {
				e += e
			}
		}
		return n
	};
	t.xorBytes = function(e, t, n) {
		var r = "";
		var i = "";
		var s = "";
		var o = 0;
		var u = 0;
		for (; n > 0; --n, ++o) {
			i = e.charCodeAt(o) ^ t.charCodeAt(o);
			if (u >= 10) {
				r += s;
				s = "";
				u = 0
			}
			s += String.fromCharCode(i);
			++u
		}
		r += s;
		return r
	};
	t.hexToBytes = function(e) {
		var t = "";
		var n = 0;
		if (e.length & 1 == 1) {
			n = 1;
			t += String.fromCharCode(parseInt(e[0], 16))
		}
		for (; n < e.length; n += 2) {
			t += String.fromCharCode(parseInt(e.substr(n, 2), 16))
		}
		return t
	};
	t.bytesToHex = function(e) {
		return t.createBuffer(e).toHex()
	};
	t.int32ToBytes = function(e) {
		return String.fromCharCode(e >> 24 & 255) + String.fromCharCode(e >> 16 & 255) + String.fromCharCode(e >> 8 & 255) + String.fromCharCode(e & 255)
	};
	var n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
	var r = [62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, 64, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51];
	t.encode64 = function(e, t) {
		var r = "";
		var i = "";
		var s, o, u;
		var a = 0;
		while (a < e.length) {
			s = e.charCodeAt(a++);
			o = e.charCodeAt(a++);
			u = e.charCodeAt(a++);
			r += n.charAt(s >> 2);
			r += n.charAt((s & 3) << 4 | o >> 4);
			if (isNaN(o)) {
				r += "=="
			} else {
				r += n.charAt((o & 15) << 2 | u >> 6);
				r += isNaN(u) ? "=" : n.charAt(u & 63)
			}
			if (t && r.length > t) {
				i += r.substr(0, t) + "\r\n";
				r = r.substr(t)
			}
		}
		i += r;
		return i
	};
	t.decode64 = function(e) {
		e = e.replace(/[^A-Za-z0-9\+\/\=]/g, "");
		var t = "";
		var n, i, s, o;
		var u = 0;
		while (u < e.length) {
			n = r[e.charCodeAt(u++) - 43];
			i = r[e.charCodeAt(u++) - 43];
			s = r[e.charCodeAt(u++) - 43];
			o = r[e.charCodeAt(u++) - 43];
			t += String.fromCharCode(n << 2 | i >> 4);
			if (s !== 64) {
				t += String.fromCharCode((i & 15) << 4 | s >> 2);
				if (o !== 64) {
					t += String.fromCharCode((s & 3) << 6 | o)
				}
			}
		}
		return t
	};
	t.encodeUtf8 = function(e) {
		return unescape(encodeURIComponent(e))
	};
	t.decodeUtf8 = function(e) {
		return decodeURIComponent(escape(e))
	};
	t.deflate = function(e, n, r) {
		n = t.decode64(e.deflate(t.encode64(n)).rval);
		if (r) {
			var i = 2;
			var s = n.charCodeAt(1);
			if (s & 32) {
				i = 6
			}
			n = n.substring(i, n.length - 4)
		}
		return n
	};
	t.inflate = function(e, n, r) {
		var i = e.inflate(t.encode64(n)).rval;
		return i === null ? null : t.decode64(i)
	};
	var i = function(e, n, r) {
			if (!e) {
				throw {
					message: "WebStorage not available."
				}
			}
			var i;
			if (r === null) {
				i = e.removeItem(n)
			} else {
				r = t.encode64(JSON.stringify(r));
				i = e.setItem(n, r)
			}
			if (typeof i !== "undefined" && i.rval !== true) {
				throw i.error
			}
		};
	var s = function(e, n) {
			if (!e) {
				throw {
					message: "WebStorage not available."
				}
			}
			var r = e.getItem(n);
			if (e.init) {
				if (r.rval === null) {
					if (r.error) {
						throw r.error
					}
					r = null
				} else {
					r = r.rval
				}
			}
			if (r !== null) {
				r = JSON.parse(t.decode64(r))
			}
			return r
		};
	var o = function(e, t, n, r) {
			var o = s(e, t);
			if (o === null) {
				o = {}
			}
			o[n] = r;
			i(e, t, o)
		};
	var u = function(e, t, n) {
			var r = s(e, t);
			if (r !== null) {
				r = n in r ? r[n] : null
			}
			return r
		};
	var a = function(e, t, n) {
			var r = s(e, t);
			if (r !== null && n in r) {
				delete r[n];
				var o = true;
				for (var u in tmp) {
					o = false;
					break
				}
				if (o) {
					r = null
				}
				i(e, t, r)
			}
		};
	var f = function(e, t) {
			i(e, t, null)
		};
	var l = function(e, t, n) {
			var r = null;
			if (typeof n === "undefined") {
				n = ["web", "flash"]
			}
			var i;
			var s = false;
			var o = null;
			for (var u in n) {
				i = n[u];
				try {
					if (i === "flash" || i === "both") {
						if (t[0] === null) {
							throw {
								message: "Flash local storage not available."
							}
						} else {
							r = e.apply(this, t);
							s = i === "flash"
						}
					}
					if (i === "web" || i === "both") {
						t[0] = localStorage;
						r = e.apply(this, t);
						s = true
					}
				} catch (a) {
					o = a
				}
				if (s) {
					break
				}
			}
			if (!s) {
				throw o
			}
			return r
		};
	t.setItem = function(e, t, n, r, i) {
		l(o, arguments, i)
	};
	t.getItem = function(e, t, n, r) {
		return l(u, arguments, r)
	};
	t.removeItem = function(e, t, n, r) {
		l(a, arguments, r)
	};
	t.clearItems = function(e, t, n) {
		l(f, arguments, n)
	};
	t.parseUrl = function(e) {
		var t = /^(https?):\/\/([^:&^\/]*):?(\d*)(.*)$/g;
		t.lastIndex = 0;
		var n = t.exec(e);
		var r = n === null ? null : {
			full: e,
			scheme: n[1],
			host: n[2],
			port: n[3],
			path: n[4]
		};
		if (r) {
			r.fullHost = r.host;
			if (r.port) {
				if (r.port !== 80 && r.scheme === "http") {
					r.fullHost += ":" + r.port
				} else {
					if (r.port !== 443 && r.scheme === "https") {
						r.fullHost += ":" + r.port
					}
				}
			} else {
				if (r.scheme === "http") {
					r.port = 80
				} else {
					if (r.scheme === "https") {
						r.port = 443
					}
				}
			}
			r.full = r.scheme + "://" + r.fullHost
		}
		return r
	};
	var c = null;
	t.getQueryVariables = function(e) {
		var t = function(e) {
				var t = {};
				var n = e.split("&");
				for (var r = 0; r < n.length; r++) {
					var i = n[r].indexOf("=");
					var s;
					var o;
					if (i > 0) {
						s = n[r].substring(0, i);
						o = n[r].substring(i + 1)
					} else {
						s = n[r];
						o = null
					}
					if (!(s in t)) {
						t[s] = []
					}
					if (o !== null) {
						t[s].push(unescape(o))
					}
				}
				return t
			};
		var n;
		if (typeof e === "undefined") {
			if (c === null) {
				if (typeof window === "undefined") {
					c = {}
				} else {
					c = t(window.location.search.substring(1))
				}
			}
			n = c
		} else {
			n = t(e)
		}
		return n
	};
	t.parseFragment = function(e) {
		var n = e;
		var r = "";
		var i = e.indexOf("?");
		if (i > 0) {
			n = e.substring(0, i);
			r = e.substring(i + 1)
		}
		var s = n.split("/");
		if (s.length > 0 && s[0] == "") {
			s.shift()
		}
		var o = r == "" ? {} : t.getQueryVariables(r);
		return {
			pathString: n,
			queryString: r,
			path: s,
			query: o
		}
	};
	t.makeRequest = function(e) {
		var n = t.parseFragment(e);
		var r = {
			path: n.pathString,
			query: n.queryString,
			getPath: function(e) {
				return typeof e === "undefined" ? n.path : n.path[e]
			},
			getQuery: function(e, t) {
				var r;
				if (typeof e === "undefined") {
					r = n.query
				} else {
					r = n.query[e];
					if (r && typeof t !== "undefined") {
						r = r[t]
					}
				}
				return r
			},
			getQueryLast: function(e, t) {
				var n;
				var i = r.getQuery(e);
				if (i) {
					n = i[i.length - 1]
				} else {
					n = t
				}
				return n
			}
		};
		return r
	};
	t.makeLink = function(e, t, n) {
		e = jQuery.isArray(e) ? e.join("/") : e;
		var r = jQuery.param(t || {});
		n = n || "";
		return e + (r.length > 0 ? "?" + r : "") + (n.length > 0 ? "#" + n : "")
	};
	t.setPath = function(e, t, n) {
		if (typeof e === "object" && e !== null) {
			var r = 0;
			var i = t.length;
			while (r < i) {
				var s = t[r++];
				if (r == i) {
					e[s] = n
				} else {
					var o = s in e;
					if (!o || o && typeof e[s] !== "object" || o && e[s] === null) {
						e[s] = {}
					}
					e = e[s]
				}
			}
		}
	};
	t.getPath = function(e, t, n) {
		var r = 0;
		var i = t.length;
		var s = true;
		while (s && r < i && typeof e === "object" && e !== null) {
			var o = t[r++];
			s = o in e;
			if (s) {
				e = e[o]
			}
		}
		return s ? e : n
	};
	t.deletePath = function(e, t) {
		if (typeof e === "object" && e !== null) {
			var n = 0;
			var r = t.length;
			while (n < r) {
				var i = t[n++];
				if (n == r) {
					delete e[i]
				} else {
					if (!(i in e) || typeof e[i] !== "object" || e[i] === null) {
						break
					}
					e = e[i]
				}
			}
		}
	};
	t.isEmpty = function(e) {
		for (var t in e) {
			if (e.hasOwnProperty(t)) {
				return false
			}
		}
		return true
	};
	t.format = function(e) {
		var t = /%./g;
		var n;
		var r;
		var i = 0;
		var s = [];
		var o = 0;
		while (n = t.exec(e)) {
			r = e.substring(o, t.lastIndex - 2);
			if (r.length > 0) {
				s.push(r)
			}
			o = t.lastIndex;
			var u = n[0][1];
			switch (u) {
			case "s":
			case "o":
				if (i < arguments.length) {
					s.push(arguments[i+++1])
				} else {
					s.push("<?>")
				}
				break;
			case "%":
				s.push("%");
				break;
			default:
				s.push("<%" + u + "?>")
			}
		}
		s.push(e.substring(o));
		return s.join("")
	};
	t.formatNumber = function(e, t, n, r) {
		var i = e,
			s = isNaN(t = Math.abs(t)) ? 2 : t;
		var o = n === undefined ? "," : n;
		var u = r === undefined ? "." : r,
			a = i < 0 ? "-" : "";
		var f = parseInt(i = Math.abs(+i || 0).toFixed(s), 10) + "";
		var l = f.length > 3 ? f.length % 3 : 0;
		return a + (l ? f.substr(0, l) + u : "") + f.substr(l).replace(/(\d{3})(?=\d)/g, "$1" + u) + (s ? o + Math.abs(i - f).toFixed(s).slice(2) : "")
	};
	t.formatSize = function(e) {
		if (e >= 1073741824) {
			e = t.formatNumber(e / 1073741824, 2, ".", "") + " GiB"
		} else {
			if (e >= 1048576) {
				e = t.formatNumber(e / 1048576, 2, ".", "") + " MiB"
			} else {
				if (e >= 1024) {
					e = t.formatNumber(e / 1024, 0) + " KiB"
				} else {
					e = t.formatNumber(e, 0) + " bytes"
				}
			}
		}
		return e
	}
})();
(function() {
	if (typeof window !== "undefined") {
		var e = window.forge = window.forge || {};
		e.prng = {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var e = window.forge = window.forge || {};
			e.md.sha1.create();
			module.exports = e.prng = {}
		}
	}
	var t = e.prng;
	t.create = function(t) {
		function n() {
			if (r.pools[0].messageLength < 32) {
				var t = 32 - r.pools[0].messageLength << 5;
				var n = "";
				var i, s, o;
				var u = Math.floor(Math.random() * 65535);
				while (n.length < t) {
					s = 16807 * (u & 65535);
					i = 16807 * (u >> 16);
					s += (i & 32767) << 16;
					s += i >> 15;
					s = (s & 2147483647) + (s >> 31);
					u = s & 4294967295;
					for (var a = 0; a < 3; ++a) {
						o = u >>> (a << 3);
						o ^= Math.floor(Math.random() * 255);
						n += String.fromCharCode(o & 255)
					}
				}
				r.collect(n)
			} else {
				var f = e.md.sha1.create();
				f.update(r.pools[0].digest().getBytes());
				r.pools[0].start();
				var l = 1;
				for (var a = 1; a < 32; ++a) {
					l = l == 31 ? 2147483648 : l << 2;
					if (l % r.reseeds === 0) {
						f.update(r.pools[a].digest().getBytes());
						r.pools[a].start()
					}
				}
				var c = f.digest().getBytes();
				f.start();
				f.update(c);
				var h = f.digest().getBytes();
				r.key = r.plugin.formatKey(c);
				r.seed = r.plugin.formatSeed(h);
				++r.reseeds;
				r.generated = 0;
				r.time = +(new Date)
			}
		}
		var r = {
			plugin: t,
			key: null,
			seed: null,
			time: null,
			reseeds: 0,
			generated: 0
		};
		var i = t.md;
		var s = new Array(32);
		for (var o = 0; o < 32; ++o) {
			s[o] = i.create()
		}
		r.pools = s;
		r.pool = 0;
		r.generate = function(t) {
			if (r.key === null) {
				n()
			}
			var i = r.plugin.cipher;
			var s = r.plugin.increment;
			var o = r.plugin.formatKey;
			var u = r.plugin.formatSeed;
			var a = e.util.createBuffer();
			while (a.length() < t) {
				var f = i(r.key, r.seed);
				r.generated += f.length;
				a.putBytes(f);
				r.key = o(i(r.key, s(r.seed)));
				r.seed = u(i(r.key, r.seed));
				if (r.generated >= 1048576) {
					var l = +(new Date);
					if (l - r.time < 100) {
						n()
					}
				}
			}
			return a.getBytes(t)
		};
		r.collect = function(e) {
			var t = e.length;
			for (var i = 0; i < t; ++i) {
				r.pools[r.pool].update(e.substr(i, 1));
				r.pool = r.pool === 31 ? 0 : r.pool + 1
			}
			if (r.pools[0].messageLength >= 32) {
				var s = +(new Date);
				if (r.time === null || s - r.time < 100) {
					n()
				}
			}
		};
		r.collectInt = function(e, t) {
			var n = "";
			do {
				t -= 8;
				n += String.fromCharCode(e >> t & 255)
			} while (t > 0);
			r.collect(n)
		};
		return r
	}
})();
(function(e) {
	if (typeof window !== "undefined") {
		var t = window.forge = window.forge || {};
		t.random = {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var t = window.forge = window.forge || {};
			module.exports = t.random = {}
		}
	}
	var n = {};
	var r = new Array(4);
	var i = t.util.createBuffer();
	n.formatKey = function(e) {
		var n = t.util.createBuffer(e);
		e = new Array(4);
		e[0] = n.getInt32();
		e[1] = n.getInt32();
		e[2] = n.getInt32();
		e[3] = n.getInt32();
		return t.aes._expandKey(e, false)
	};
	n.formatSeed = function(e) {
		tmp = t.util.createBuffer(e);
		e = new Array(4);
		e[0] = tmp.getInt32();
		e[1] = tmp.getInt32();
		e[2] = tmp.getInt32();
		e[3] = tmp.getInt32();
		return e
	};
	n.cipher = function(e, n) {
		t.aes._updateBlock(e, n, r, false);
		i.putInt32(r[0]);
		i.putInt32(r[1]);
		i.putInt32(r[2]);
		i.putInt32(r[3]);
		return i.getBytes()
	};
	n.increment = function(e) {
		++e[3];
		return e
	};
	// n.md = t.md.sha1;
	// var s = t.prng.create(n);
	s.collectInt(+(new Date), 32);
	if (typeof navigator !== "undefined") {
		var o = "";
		for (var u in navigator) {
			if (typeof navigator[u] == "string") {
				o += navigator[u]
			}
		}
		s.collect(o);
		o = null
	}
	if (e !== null) {
		e().mousemove(function(e) {
			s.collectInt(e.clientX, 16);
			s.collectInt(e.clientY, 16)
		});
		e().keypress(function(e) {
			s.collectInt(e.charCode, 8)
		})
	}
	t.random.getBytes = function(e) {
		return s.generate(e)
	}
});
(typeof jQuery !== "undefined" ? jQuery : null);
(function() {
	if (typeof window !== "undefined") {
		var e = window.forge = window.forge || {};
		e.aes = {}
	} else {
		if (typeof module !== "undefined" && module.exports) {
			var e = window.forge = window.forge || {};
			module.exports = e.aes = {}
		}
	}
	var t = false;
	var n = 4;
	var r;
	var i;
	var s;
	var o;
	var u;
	var a = function() {
			t = true;
			s = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54];
			var e = new Array(256);
			for (var n = 0; n < 128; ++n) {
				e[n] = n << 1;
				e[n + 128] = n + 128 << 1 ^ 283
			}
			r = new Array(256);
			i = new Array(256);
			o = new Array(4);
			u = new Array(4);
			for (var n = 0; n < 4; ++n) {
				o[n] = new Array(256);
				u[n] = new Array(256)
			}
			var a = 0,
				f = 0,
				l, c, h, p, d, v, m;
			for (var n = 0; n < 256; ++n) {
				p = f ^ f << 1 ^ f << 2 ^ f << 3 ^ f << 4;
				p = p >> 8 ^ p & 255 ^ 99;
				r[a] = p;
				i[p] = a;
				d = e[p];
				l = e[a];
				c = e[l];
				h = e[c];
				v = d << 24 ^ p << 16 ^ p << 8 ^ (p ^ d);
				m = (l ^ c ^ h) << 24 ^ (a ^ h) << 16 ^ (a ^ c ^ h) << 8 ^ (a ^ l ^ h);
				for (var g = 0; g < 4; ++g) {
					o[g][a] = v;
					u[g][p] = m;
					v = v << 24 | v >>> 8;
					m = m << 24 | m >>> 8
				}
				if (a === 0) {
					a = f = 1
				} else {
					a = l ^ e[e[e[l ^ h]]];
					f ^= e[e[f]]
				}
			}
		};
	var f = function(e, t) {
			var i = e.slice(0);
			var o, a = 1;
			var f = i.length;
			var l = f + 6 + 1;
			var c = n * l;
			for (var h = f; h < c; ++h) {
				o = i[h - 1];
				if (h % f === 0) {
					o = r[o >>> 16 & 255] << 24 ^ r[o >>> 8 & 255] << 16 ^ r[o & 255] << 8 ^ r[o >>> 24] ^ s[a] << 24;
					a++
				} else {
					if (f > 6 && h % f == 4) {
						o = r[o >>> 24] << 24 ^ r[o >>> 16 & 255] << 16 ^ r[o >>> 8 & 255] << 8 ^ r[o & 255]
					}
				}
				i[h] = i[h - f] ^ o
			}
			if (t) {
				var p;
				var d = u[0];
				var v = u[1];
				var m = u[2];
				var g = u[3];
				var y = i.slice(0);
				var c = i.length;
				for (var h = 0, b = c - n; h < c; h += n, b -= n) {
					if (h === 0 || h === c - n) {
						y[h] = i[b];
						y[h + 1] = i[b + 3];
						y[h + 2] = i[b + 2];
						y[h + 3] = i[b + 1]
					} else {
						for (var w = 0; w < n; ++w) {
							p = i[b + w];
							y[h + (3 & -w)] = d[r[p >>> 24]] ^ v[r[p >>> 16 & 255]] ^ m[r[p >>> 8 & 255]] ^ g[r[p & 255]]
						}
					}
				}
				i = y
			}
			return i
		};
	var l = function(e, t, n, s) {
			var a = e.length / 4 - 1;
			var f, l, c, h, p;
			if (s) {
				f = u[0];
				l = u[1];
				c = u[2];
				h = u[3];
				p = i
			} else {
				f = o[0];
				l = o[1];
				c = o[2];
				h = o[3];
				p = r
			}
			var d, v, m, g, y, b, w;
			d = t[0] ^ e[0];
			v = t[s ? 3 : 1] ^ e[1];
			m = t[2] ^ e[2];
			g = t[s ? 1 : 3] ^ e[3];
			var E = 3;
			for (var S = 1; S < a; ++S) {
				y = f[d >>> 24] ^ l[v >>> 16 & 255] ^ c[m >>> 8 & 255] ^ h[g & 255] ^ e[++E];
				b = f[v >>> 24] ^ l[m >>> 16 & 255] ^ c[g >>> 8 & 255] ^ h[d & 255] ^ e[++E];
				w = f[m >>> 24] ^ l[g >>> 16 & 255] ^ c[d >>> 8 & 255] ^ h[v & 255] ^ e[++E];
				g = f[g >>> 24] ^ l[d >>> 16 & 255] ^ c[v >>> 8 & 255] ^ h[m & 255] ^ e[++E];
				d = y;
				v = b;
				m = w
			}
			n[0] = p[d >>> 24] << 24 ^ p[v >>> 16 & 255] << 16 ^ p[m >>> 8 & 255] << 8 ^ p[g & 255] ^ e[++E];
			n[s ? 3 : 1] = p[v >>> 24] << 24 ^ p[m >>> 16 & 255] << 16 ^ p[g >>> 8 & 255] << 8 ^ p[d & 255] ^ e[++E];
			n[2] = p[m >>> 24] << 24 ^ p[g >>> 16 & 255] << 16 ^ p[d >>> 8 & 255] << 8 ^ p[v & 255] ^ e[++E];
			n[s ? 1 : 3] = p[g >>> 24] << 24 ^ p[d >>> 16 & 255] << 16 ^ p[v >>> 8 & 255] << 8 ^ p[m & 255] ^ e[++E]
		};
	var c = function(r, i, s, o) {
			var u = null;
			if (!t) {
				a()
			}
			if (r.constructor == String && (r.length == 16 || r.length == 24 || r.length == 32)) {
				r = e.util.createBuffer(r)
			} else {
				if (r.constructor == Array && (r.length == 16 || r.length == 24 || r.length == 32)) {
					var c = r;
					var r = e.util.createBuffer();
					for (var h = 0; h < c.length; ++h) {
						r.putByte(c[h])
					}
				}
			}
			if (r.constructor != Array) {
				var c = r;
				r = [];
				var p = c.length();
				if (p == 16 || p == 24 || p == 32) {
					p = p >>> 2;
					for (var h = 0; h < p; ++h) {
						r.push(c.getInt32())
					}
				}
			}
			if (r.constructor == Array && (r.length == 4 || r.length == 6 || r.length == 8)) {
				var d = f(r, o);
				var v = n << 2;
				var m;
				var g;
				var y;
				var b;
				var w;
				var E;
				u = {
					output: null
				};
				u.update = function(e) {
					if (!E) {
						m.putBuffer(e)
					}
					var t = o && !E ? v << 1 : v;
					while (m.length() >= t) {
						if (o) {
							for (var r = 0; r < n; ++r) {
								y[r] = m.getInt32()
							}
						} else {
							for (var r = 0; r < n; ++r) {
								y[r] = w[r] ^ m.getInt32()
							}
						}
						l(d, y, b, o);
						if (o) {
							for (var r = 0; r < n; ++r) {
								g.putInt32(w[r] ^ b[r])
							}
							w = y.slice(0)
						} else {
							for (var r = 0; r < n; ++r) {
								g.putInt32(b[r])
							}
							w = b
						}
					}
				};
				u.finish = function(e) {
					var t = true;
					if (!o) {
						if (e) {
							t = e(v, m, o)
						} else {
							var r = m.length() == v ? v : v - m.length();
							m.fillWithByte(r, r)
						}
					}
					if (t) {
						E = true;
						u.update()
					}
					if (o) {
						t = m.length() === 0;
						if (t) {
							if (e) {
								t = e(v, g, o)
							} else {
								var i = g.length();
								var s = g.at(i - 1);
								if (s > n << 2) {
									t = false
								} else {
									g.truncate(s)
								}
							}
						}
					}
					return t
				};
				u.start = function(t, r) {
					t = t || w.slice(0);
					if (t.constructor == String && t.length == 16) {
						t = e.util.createBuffer(t)
					} else {
						if (t.constructor == Array && t.length == 16) {
							var i = t;
							var t = e.util.createBuffer();
							for (var s = 0; s < 16; ++s) {
								t.putByte(i[s])
							}
						}
					}
					if (t.constructor != Array) {
						var i = t;
						t = new Array(4);
						t[0] = i.getInt32();
						t[1] = i.getInt32();
						t[2] = i.getInt32();
						t[3] = i.getInt32()
					}
					m = e.util.createBuffer();
					g = r || e.util.createBuffer();
					w = t.slice(0);
					y = new Array(n);
					b = new Array(n);
					E = false;
					u.output = g
				};
				if (i !== null) {
					u.start(i, s)
				}
			}
			return u
		};
	e.aes.startEncrypting = function(e, t, n) {
		return c(e, t, n, false)
	};
	e.aes.createEncryptionCipher = function(e) {
		return c(e, null, null, false)
	};
	e.aes.startDecrypting = function(e, t, n) {
		return c(e, t, n, true)
	};
	e.aes.createDecryptionCipher = function(e) {
		return c(e, null, null, true)
	};
	e.aes._expandKey = function(e, n) {
		if (!t) {
			a()
		}
		return f(e, n)
	};
	e.aes._updateBlock = l
})()